Merge from emacs-24; up to 2012-12-06T01:39:03Z!monnier@iro.umontreal.ca
[bpt/emacs.git] / src / term.c
index 8ce2efc..d76562b 100644 (file)
@@ -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 <http://www.gnu.org/licenses/>.  */
 /* New redisplay, TTY faces by Gerd Moellmann <gerd@gnu.org>.  */
 
 #include <config.h>
-#include <stdio.h>
-#include <ctype.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
 #include <sys/file.h>
+#include <sys/time.h>
 #include <unistd.h>
-#include <signal.h>
-#include <setjmp.h>
 
 #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;
-
 \f
 
 #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;
-}
-
-
 \f
 /***********************************************************************
                                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;
+}
+
 \f
 
 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);
 }
 
-\f
-
-/* 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);
-}
-
-\f
-
 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