X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/cd4eb164a9cb5fd4df2290423830471d6086fd1e..0877d0dc24ee792b9b14592869ea1aa0934aee58:/src/term.c diff --git a/src/term.c b/src/term.c index 8ce2efc092..d76562bb4d 100644 --- a/src/term.c +++ b/src/term.c @@ -1,6 +1,6 @@ /* Terminal control module for terminals described by TERMCAP - Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2012 - Free Software Foundation, Inc. + Copyright (C) 1985-1987, 1993-1995, 1998, 2000-2013 Free Software + Foundation, Inc. This file is part of GNU Emacs. @@ -20,20 +20,18 @@ along with GNU Emacs. If not, see . */ /* New redisplay, TTY faces by Gerd Moellmann . */ #include -#include -#include #include +#include +#include #include +#include #include -#include -#include #include "lisp.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" @@ -58,17 +56,10 @@ static int been_here = -1; #include "xterm.h" #endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif - -#ifndef O_NOCTTY -#define O_NOCTTY 0 -#endif - /* The name of the default console device. */ #ifdef WINDOWSNT #define DEV_TTY "CONOUT$" +#include "w32term.h" #else #define DEV_TTY "/dev/tty" #endif @@ -85,11 +76,11 @@ 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 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) \ @@ -135,10 +126,6 @@ enum no_color_bit static int max_frame_cols; -/* Non-zero if we have dropped our controlling tty and therefore - should not open a frame on stdout. */ -static int no_controlling_tty; - #ifdef HAVE_GPM @@ -755,13 +742,13 @@ tty_write_glyphs (struct frame *f, struct glyph *string, int len) conversion_buffer = encode_terminal_code (string, n, coding); if (coding->produced > 0) { - BLOCK_INPUT; + block_input (); fwrite (conversion_buffer, 1, coding->produced, tty->output); if (ferror (tty->output)) clearerr (tty->output); if (tty->termscript) fwrite (conversion_buffer, 1, coding->produced, tty->termscript); - UNBLOCK_INPUT; + unblock_input (); } string += n; @@ -816,13 +803,13 @@ tty_write_glyphs_with_face (register struct frame *f, register struct glyph *str conversion_buffer = encode_terminal_code (string, len, coding); if (coding->produced > 0) { - BLOCK_INPUT; + block_input (); fwrite (conversion_buffer, 1, coding->produced, tty->output); if (ferror (tty->output)) clearerr (tty->output); if (tty->termscript) fwrite (conversion_buffer, 1, coding->produced, tty->termscript); - UNBLOCK_INPUT; + unblock_input (); } /* Turn appearance modes off. */ @@ -902,13 +889,13 @@ tty_insert_glyphs (struct frame *f, struct glyph *start, int len) if (coding->produced > 0) { - BLOCK_INPUT; + block_input (); fwrite (conversion_buffer, 1, coding->produced, tty->output); if (ferror (tty->output)) clearerr (tty->output); if (tty->termscript) fwrite (conversion_buffer, 1, coding->produced, tty->termscript); - UNBLOCK_INPUT; + unblock_input (); } OUTPUT1_IF (tty, tty->TS_pad_inserted_char); @@ -966,8 +953,8 @@ tty_ins_del_lines (struct frame *f, int vpos, int n) 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; + int i = eabs (n); + char *buf; /* If the lines below the insertion are being pushed into the end of the window, this is the same as clearing; @@ -1332,7 +1319,7 @@ term_get_fkeys_1 (void) /* This can happen if CANNOT_DUMP or with strange options. */ if (!KEYMAPP (KVAR (kboard, Vinput_decode_map))) - KVAR (kboard, Vinput_decode_map) = Fmake_sparse_keymap (Qnil); + kset_input_decode_map (kboard, Fmake_sparse_keymap (Qnil)); for (i = 0; i < (sizeof (keys)/sizeof (keys[0])); i++) { @@ -1458,7 +1445,7 @@ append_glyph (struct it *it) 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]; @@ -1498,7 +1485,7 @@ append_glyph (struct it *it) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } else @@ -1545,7 +1532,7 @@ produce_glyphs (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 + eassert (it->what == IT_CHARACTER || it->what == IT_COMPOSITION || it->what == IT_STRETCH || it->what == IT_GLYPHLESS); @@ -1632,7 +1619,7 @@ produce_glyphs (struct it *it) { 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); } } @@ -1656,7 +1643,7 @@ append_composite_glyph (struct it *it) { 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]) { @@ -1695,7 +1682,7 @@ append_composite_glyph (struct it *it) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } else @@ -1748,7 +1735,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str) 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]; @@ -1780,7 +1767,7 @@ append_glyphless_glyph (struct it *it, int face_id, const char *str) { glyph->resolved_level = it->bidi_it.resolved_level; if ((it->bidi_it.type & 7) != it->bidi_it.type) - abort (); + emacs_abort (); glyph->bidi_type = it->bidi_it.type; } else @@ -1850,8 +1837,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) len = 1; else if (len > 4) len = 4; - sprintf (buf, "[%.*s]", len, str); - len += 2; + len = sprintf (buf, "[%.*s]", len, str); str = buf; } else @@ -1871,7 +1857,7 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) } 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)); @@ -1885,67 +1871,6 @@ produce_glyphless_glyph (struct it *it, int for_no_font, Lisp_Object acronym) 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; -} - - /*********************************************************************** Faces @@ -2067,7 +1992,7 @@ turn_off_face (struct frame *f, int face_id) struct face *face = FACE_FROM_ID (f, face_id); struct tty_display_info *tty = FRAME_TTY (f); - xassert (face != NULL); + eassert (face != NULL); if (tty->TS_exit_attribute_mode) { @@ -2132,7 +2057,7 @@ DEFUN ("tty-display-color-p", Ftty_display_color_p, Stty_display_color_p, 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); @@ -2149,7 +2074,7 @@ DEFUN ("tty-display-color-cells", Ftty_display_color_cells, 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); @@ -2270,11 +2195,10 @@ set_tty_color_mode (struct tty_display_info *tty, struct frame *f) if (mode != tty->previous_color_mode) { - 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); + safe_call (1, intern ("tty-set-up-initial-frame-faces")); } } @@ -2313,7 +2237,7 @@ get_named_tty (const char *name) struct terminal *t; if (!name) - abort (); + emacs_abort (); for (t = terminal_list; t; t = t->next_terminal) { @@ -2371,7 +2295,7 @@ no effect if used on a non-tty terminal. 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); @@ -2381,6 +2305,21 @@ TERMINAL does not refer to a text-only terminal. */) 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; +} + DEFUN ("suspend-tty", Fsuspend_tty, Ssuspend_tty, 0, 1, 0, @@ -2596,6 +2535,18 @@ term_mouse_movement (FRAME_PTR frame, Gpm_Event *event) 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 @@ -2615,7 +2566,6 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, Lisp_Object *y, Time *timeptr) { struct timeval now; - Time sec, usec; *fp = SELECTED_FRAME (); (*fp)->mouse_moved = 0; @@ -2626,9 +2576,7 @@ term_mouse_position (FRAME_PTR *fp, int insist, Lisp_Object *bar_window, 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. @@ -2652,7 +2600,7 @@ term_mouse_click (struct input_event *result, Gpm_Event *event, } } 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; @@ -2834,13 +2782,10 @@ DEFUN ("gpm-mouse-stop", Fgpm_mouse_stop, Sgpm_mouse_stop, 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)); + emacs_abort (); t->display_info = FRAME_TERMINAL (f)->display_info.tty; @@ -2853,7 +2798,7 @@ static void tty_free_frame_resources (struct frame *f) { if (! FRAME_TERMCAP_P (f)) - abort (); + emacs_abort (); if (FRAME_FACE_CACHE (f)) free_frame_faces (f); @@ -2869,7 +2814,7 @@ static void tty_free_frame_resources (struct frame *f) { if (! FRAME_TERMCAP_P (f) && ! FRAME_MSDOS_P (f)) - abort (); + emacs_abort (); if (FRAME_FACE_CACHE (f)) free_frame_faces (f); @@ -2962,34 +2907,9 @@ set_tty_hooks (struct terminal *terminal) static void dissociate_if_controlling_tty (int fd) { -#ifndef DOS_NT - int pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ - if (pgid != -1) - { -#if defined (USG5) - 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); - if (fd != -1 && ioctl (fd, TIOCNOTTY, 0) != -1) - { - no_controlling_tty = 1; - } - if (fd != -1) - emacs_close (fd); - sigunblock (sigmask (SIGTTOU)); -#else - /* Unknown system. */ - croak (); -#endif /* ! TIOCNOTTY */ -#endif /* ! USG */ - } -#endif /* !DOS_NT */ + pid_t pgid = tcgetpgrp (fd); /* If tcgetpgrp succeeds, fd is the ctty. */ + if (0 <= pgid) + setsid (); } /* Create a termcap display on the tty device with the given name and @@ -3041,9 +2961,9 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) 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->top_frame = Qnil; tty->next = tty_list; tty_list = tty; @@ -3051,7 +2971,7 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) 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; @@ -3062,22 +2982,18 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) set_tty_hooks (terminal); { - int fd; + /* Open the terminal device. */ FILE *file; -#ifdef O_IGNORE_CTTY - if (!ctty) - /* Open the terminal device. Don't recognize it as our - controlling terminal, and don't make it the controlling tty - if we don't have one at the moment. */ - fd = emacs_open (name, O_RDWR | O_IGNORE_CTTY | O_NOCTTY, 0); - 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); + /* If !ctty, don't recognize it as our controlling terminal, and + don't make it the controlling tty if we don't have one now. + + 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. */ + int flags = O_RDWR | O_NOCTTY | (ctty ? 0 : O_IGNORE_CTTY); + int fd = emacs_open (name, flags, 0); tty->name = xstrdup (name); terminal->name = xstrdup (name); @@ -3096,10 +3012,8 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) name); } -#ifndef O_IGNORE_CTTY - if (!ctty) + if (!O_IGNORE_CTTY && !ctty) dissociate_if_controlling_tty (fd); -#endif file = fdopen (fd, "w+"); tty->input = file; @@ -3112,13 +3026,18 @@ init_tty (const char *name, const char *terminal_type, int must_succeed) 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. */ - sigblock (sigmask (SIGTTOU)); - status = tgetent (tty->termcap_term_buffer, terminal_type); - sigunblock (sigmask (SIGTTOU)); + { + sigset_t blocked; + sigemptyset (&blocked); + sigaddset (&blocked, SIGTTOU); + pthread_sigmask (SIG_BLOCK, &blocked, 0); + status = tgetent (tty->termcap_term_buffer, terminal_type); + pthread_sigmask (SIG_UNBLOCK, &blocked, 0); + } if (status < 0) { @@ -3150,10 +3069,10 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ #ifndef TERMINFO if (strlen (tty->termcap_term_buffer) >= buffer_size) - abort (); + emacs_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); @@ -3272,7 +3191,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ FrameCols (tty) = FRAME_COLS (f); tty->specified_window = FRAME_LINES (f); - FRAME_CAN_HAVE_SCROLL_BARS (f) = 0; FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none; terminal->char_ins_del_ok = 1; baud_rate = 19200; @@ -3321,9 +3239,9 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ 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; + kset_window_system (terminal->kboard, Qnil); terminal->kboard->next_kboard = all_kboards; all_kboards = terminal->kboard; terminal->kboard->reference_count++; @@ -3444,10 +3362,6 @@ use the Bourne shell command `TERM=... export TERM' (C-shell:\n\ = tty->TS_delete_mode && tty->TS_insert_mode && !strcmp (tty->TS_delete_mode, tty->TS_insert_mode); - tty->se_is_so = (tty->TS_standout_mode - && tty->TS_end_standout_mode - && !strcmp (tty->TS_standout_mode, tty->TS_end_standout_mode)); - UseTabs (tty) = tabs_safe_p (fileno (tty->input)) && TabWidth (tty) == 8; terminal->scroll_region_ok @@ -3509,7 +3423,7 @@ maybe_fatal (int must_succeed, struct terminal *terminal, verror (str1, ap); va_end (ap); - abort (); + emacs_abort (); } void @@ -3536,7 +3450,7 @@ delete_tty (struct terminal *terminal) return; if (terminal->type != output_termcap) - abort (); + emacs_abort (); tty = terminal->display_info.tty; @@ -3550,7 +3464,7 @@ delete_tty (struct terminal *terminal) if (! p) /* This should not happen. */ - abort (); + emacs_abort (); p->next = tty->next; tty->next = 0; @@ -3581,26 +3495,9 @@ delete_tty (struct terminal *terminal) xfree (tty->termcap_strings_buffer); xfree (tty->termcap_term_buffer); - memset (tty, 0, sizeof (struct tty_display_info)); xfree (tty); } - - -/* Mark the pointers in the tty_display_info objects. - Called by Fgarbage_collect. */ - -void -mark_ttys (void) -{ - struct tty_display_info *tty; - - for (tty = tty_list; tty; tty = tty->next) - mark_object (tty->top_frame); -} - - - void syms_of_term (void) { @@ -3614,14 +3511,14 @@ This variable can be used by terminal emulator packages. */); #endif DEFVAR_LISP ("suspend-tty-functions", Vsuspend_tty_functions, - doc: /* Functions to be run after suspending a tty. + doc: /* Functions run after suspending a tty. 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. + doc: /* Functions run after resuming a tty. The functions are run with one argument, the terminal object that was revived. See `resume-tty'. */); Vresume_tty_functions = Qnil; @@ -3638,6 +3535,7 @@ bigger, or it may make it blink, or it may do nothing at all. */); defsubr (&Stty_no_underline); defsubr (&Stty_type); defsubr (&Scontrolling_tty_p); + defsubr (&Stty_top_frame); defsubr (&Ssuspend_tty); defsubr (&Sresume_tty); #ifdef HAVE_GPM