(VALBITS, GCTYPEBITS): Deleted; default is better.
[bpt/emacs.git] / src / term.c
index cd9e5a8..ae0032b 100644 (file)
@@ -1,5 +1,5 @@
 /* terminal control module for terminals described by TERMCAP
-   Copyright (C) 1985, 1986, 1987, 1992, 1993 Free Software Foundation, Inc.
+   Copyright (C) 1985, 1986, 1987, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -18,9 +18,9 @@ along with GNU Emacs; see the file COPYING.  If not, write to
 the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 
+#include <config.h>
 #include <stdio.h>
 #include <ctype.h>
-#include "config.h"
 #include "termchar.h"
 #include "termopts.h"
 #include "cm.h"
@@ -31,6 +31,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #include "termhooks.h"
 #include "keyboard.h"
 
+extern Lisp_Object Fmake_sparse_keymap ();
+
 #define max(a, b) ((a) > (b) ? (a) : (b))
 #define min(a, b) ((a) < (b) ? (a) : (b))
 
@@ -40,7 +42,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define OUTPUT_IF(a) { if (a) tputs (a, FRAME_HEIGHT (selected_frame) - curY, cmputc); }
 #define OUTPUT1_IF(a) { if (a) tputs (a, 1, cmputc); }
 
-/* Terminal charateristics that higher levels want to look at.
+/* Terminal characteristics that higher levels want to look at.
    These are all extern'd in termchar.h */
 
 int must_write_spaces;         /* Nonzero means spaces in the text
@@ -52,13 +54,12 @@ int line_ins_del_ok;                /* Terminal can insert and delete lines */
 int char_ins_del_ok;           /* Terminal can insert and delete chars */
 int scroll_region_ok;          /* Terminal supports setting the
                                   scroll window */
+int scroll_region_cost;                /* Cost of setting a scroll window,
+                                  measured in characters */
 int memory_below_frame;                /* Terminal remembers lines
                                   scrolled off bottom */
 int fast_clear_end_of_line;    /* Terminal has a `ce' string */
 
-int dont_calculate_costs;      /* Nonzero means don't bother computing */
-                               /* various cost tables; we won't use them.  */
-
 /* Nonzero means no need to redraw the entire frame on resuming
    a suspended Emacs.  This is useful on terminals with multiple pages,
    where one page is used for Emacs and another for all else. */
@@ -93,16 +94,18 @@ int (*set_terminal_window_hook) ();
 
 int (*read_socket_hook) ();
 
+int (*frame_up_to_date_hook) ();
+
 /* Return the current position of the mouse.
 
    Set *f to the frame the mouse is in, or zero if the mouse is in no
    Emacs frame.  If it is set to zero, all the other arguments are
    garbage.
 
-   If the motion started in a scrollbar, set *bar_window to the
-   scrollbar's window, *part to the part the mouse is currently over,
-   *x to the position of the mouse along the scrollbar, and *y to the
-   overall length of the scrollbar.
+   If the motion started in a scroll bar, set *bar_window to the
+   scroll bar's window, *part to the part the mouse is currently over,
+   *x to the position of the mouse along the scroll bar, and *y to the
+   overall length of the scroll bar.
 
    Otherwise, set *bar_window to Qnil, and *x and *y to the column and
    row of the character cell the mouse is over.
@@ -113,7 +116,7 @@ int (*read_socket_hook) ();
    event arrives.  */
 void (*mouse_position_hook) ( /* FRAME_PTR *f,
                                 Lisp_Object *bar_window,
-                                enum scrollbar_part *part,
+                                enum scroll_bar_part *part,
                                 Lisp_Object *x,
                                 Lisp_Object *y,
                                 unsigned long *time */ );
@@ -137,54 +140,54 @@ void (*frame_rehighlight_hook) ( /* FRAME_PTR f */ );
    windows.  */
 void (*frame_raise_lower_hook) ( /* FRAME_PTR f, int raise */ );
 
-/* Set the vertical scrollbar for WINDOW to have its upper left corner
+/* Set the vertical scroll bar for WINDOW to have its upper left corner
    at (TOP, LEFT), and be LENGTH rows high.  Set its handle to
    indicate that we are displaying PORTION characters out of a total
    of WHOLE characters, starting at POSITION.  If WINDOW doesn't yet
-   have a scrollbar, create one for it.  */
-void (*set_vertical_scrollbar_hook)
+   have a scroll bar, create one for it.  */
+void (*set_vertical_scroll_bar_hook)
      ( /* struct window *window,
          int portion, int whole, int position */ );
 
 
 /* The following three hooks are used when we're doing a thorough
-   redisplay of the frame.  We don't explicitly know which scrollbars
+   redisplay of the frame.  We don't explicitly know which scroll bars
    are going to be deleted, because keeping track of when windows go
    away is a real pain - can you say set-window-configuration?
    Instead, we just assert at the beginning of redisplay that *all*
-   scrollbars are to be removed, and then save scrollbars from the
+   scroll bars are to be removed, and then save scroll bars from the
    firey pit when we actually redisplay their window.  */
 
-/* Arrange for all scrollbars on FRAME to be removed at the next call
-   to `*judge_scrollbars_hook'.  A scrollbar may be spared if
-   `*redeem_scrollbar_hook' is applied to its window before the judgement. 
+/* Arrange for all scroll bars on FRAME to be removed at the next call
+   to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
+   `*redeem_scroll_bar_hook' is applied to its window before the judgement. 
 
    This should be applied to each frame each time its window tree is
-   redisplayed, even if it is not displaying scrollbars at the moment;
-   if the HAS_SCROLLBARS flag has just been turned off, only calling
-   this and the judge_scrollbars_hook will get rid of them.
+   redisplayed, even if it is not displaying scroll bars at the moment;
+   if the HAS_SCROLL_BARS flag has just been turned off, only calling
+   this and the judge_scroll_bars_hook will get rid of them.
 
    If non-zero, this hook should be safe to apply to any frame,
-   whether or not it can support scrollbars, and whether or not it is
+   whether or not it can support scroll bars, and whether or not it is
    currently displaying them.  */
-void (*condemn_scrollbars_hook)( /* FRAME_PTR *frame */ );
+void (*condemn_scroll_bars_hook)( /* FRAME_PTR *frame */ );
 
-/* Unmark WINDOW's scrollbar for deletion in this judgement cycle.
-   Note that it's okay to redeem a scrollbar that is not condemned.  */
-void (*redeem_scrollbar_hook)( /* struct window *window */ );
+/* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
+   Note that it's okay to redeem a scroll bar that is not condemned.  */
+void (*redeem_scroll_bar_hook)( /* struct window *window */ );
 
-/* Remove all scrollbars on FRAME that haven't been saved since the
-   last call to `*condemn_scrollbars_hook'.  
+/* Remove all scroll bars on FRAME that haven't been saved since the
+   last call to `*condemn_scroll_bars_hook'.  
 
    This should be applied to each frame after each time its window
-   tree is redisplayed, even if it is not displaying scrollbars at the
-   moment; if the HAS_SCROLLBARS flag has just been turned off, only
-   calling this and condemn_scrollbars_hook will get rid of them.
+   tree is redisplayed, even if it is not displaying scroll bars at the
+   moment; if the HAS_SCROLL_BARS flag has just been turned off, only
+   calling this and condemn_scroll_bars_hook will get rid of them.
 
    If non-zero, this hook should be safe to apply to any frame,
-   whether or not it can support scrollbars, and whether or not it is
+   whether or not it can support scroll bars, and whether or not it is
    currently displaying them.  */
-void (*judge_scrollbars_hook)( /* FRAME_PTR *FRAME */ );
+void (*judge_scroll_bars_hook)( /* FRAME_PTR *FRAME */ );
 
 
 /* Strings, numbers and flags taken from the termcap entry.  */
@@ -279,8 +282,25 @@ int specified_window;
 
 FRAME_PTR updating_frame;
 
+/* Provided for lisp packages.  */
+static int system_uses_terminfo;
+
 char *tparam ();
+
+extern char *tgetstr ();
 \f
+
+#ifdef WINDOWSNT
+/* We aren't X windows, but we aren't termcap either.  This makes me
+   uncertain as to what value to use for frame.output_method.  For
+   this file, we'll define FRAME_TERMCAP_P to be zero so that our
+   output hooks get called instead of the termcap functions.  Probably
+   the best long-term solution is to define an output_windows_nt...  */
+
+#undef FRAME_TERMCAP_P
+#define FRAME_TERMCAP_P(_f_) 0
+#endif /* WINDOWSNT */
+
 ring_bell ()
 {
   if (! FRAME_TERMCAP_P (selected_frame))
@@ -382,7 +402,7 @@ set_scroll_region (start, stop)
       buf = tparam (TS_set_window, 0, 0, start, 0, stop, FRAME_WIDTH (selected_frame));
     }
   OUTPUT (buf);
-  free (buf);
+  xfree (buf);
   losecursor ();
 }
 \f
@@ -587,7 +607,7 @@ clear_to_end ()
 {
   register int i;
 
-  if (clear_to_end_hook && FRAME_TERMCAP_P (updating_frame))
+  if (clear_to_end_hook && FRAME_TERMCAP_P (updating_frame))
     {
       (*clear_to_end_hook) ();
       return;
@@ -787,7 +807,7 @@ insert_glyphs (start, len)
     {
       buf = tparam (TS_ins_multi_chars, 0, 0, len);
       OUTPUT1 (buf);
-      free (buf);
+      xfree (buf);
       if (start)
        write_glyphs (start, len);
       return;
@@ -851,7 +871,7 @@ delete_glyphs (n)
     {
       buf = tparam (TS_del_multi_chars, 0, 0, n);
       OUTPUT1 (buf);
-      free (buf);
+      xfree (buf);
     }
   else
     for (i = 0; i < n; i++)
@@ -896,7 +916,7 @@ ins_del_lines (vpos, n)
       background_highlight ();
       buf = tparam (multi, 0, 0, i);
       OUTPUT (buf);
-      free (buf);
+      xfree (buf);
     }
   else if (single)
     {
@@ -1061,25 +1081,25 @@ calculate_ins_del_char_costs (frame)
     *p++ = (ins_startup_cost += ins_cost_per_char);
 }
 
-#ifdef HAVE_X_WINDOWS
-extern int x_screen_planes;
-#endif
+extern do_line_insertion_deletion_costs ();
 
 calculate_costs (frame)
      FRAME_PTR frame;
 {
-  register char *f = TS_set_scroll_region ?
-                       TS_set_scroll_region
-                    : TS_set_scroll_region_1;
+  register char *f = (TS_set_scroll_region
+                     ? TS_set_scroll_region
+                     : TS_set_scroll_region_1);
 
-  if (dont_calculate_costs)
-    return;
+  FRAME_COST_BAUD_RATE (frame) = baud_rate;
 
+  scroll_region_cost = string_cost (f);
 #ifdef HAVE_X_WINDOWS
   if (FRAME_X_P (frame))
     {
       do_line_insertion_deletion_costs (frame, 0, ".5*", 0, ".5*",
-                                       0, 0, x_screen_planes);
+                                       0, 0,
+                                       x_screen_planes (frame));
+      scroll_region_cost = 0;
       return;
     }
 #endif
@@ -1140,68 +1160,140 @@ calculate_costs (frame)
   cmcostinit ();               /* set up cursor motion costs */
 }
 \f
-/* Find the escape codes sent by the function keys for Vfunction_key_map.
-   This function scans the termcap function key sequence entries, and 
-   adds entries to Vfunction_key_map for each function key it finds.  */
-
 struct fkey_table {
   char *cap, *name;
 };
 
+  /* Termcap capability names that correspond directly to X keysyms.
+     Some of these (marked "terminfo") aren't supplied by old-style
+     (Berkeley) termcap entries.  They're listed in X keysym order;
+     except we put the keypad keys first, so that if they clash with
+     other keys (as on the IBM PC keyboard) they get overridden.
+  */
+
 static struct fkey_table keys[] = {
-  "kl", "left",
-  "kr", "right",
-  "ku", "up",
-  "kd", "down",
-  "K2", "center",
-  "k1", "f1",
-  "k2", "f2",
-  "k3", "f3",
-  "k4", "f4",
-  "k5", "f5",
-  "k6", "f6",
-  "k7", "f7",
-  "k8", "f8",
-  "k9", "f9",
-  "F1", "f11",
-  "F2", "f12",
-  "kh", "home",
-  "kH", "home-down",
-  "ka", "clear-tabs",
-  "kt", "clear-tab",
-  "kT", "set-tab",
-  "kC", "clear",
-  "kL", "deleteline",
-  "kM", "exit-insert",
-  "kE", "clear-eol",
-  "kS", "clear-eos",
-  "kI", "insert",
-  "kA", "insertline",
-  "kN", "next",
-  "kP", "prior",
-  "kF", "scroll-forward",
-  "kR", "scroll-reverse"
+  "kh", "home",                /* termcap */
+  "kl", "left",                /* termcap */
+  "ku", "up",          /* termcap */
+  "kr", "right",       /* termcap */
+  "kd", "down",                /* termcap */
+  "%8", "prior",       /* terminfo */
+  "%5", "next",                /* terminfo */
+  "@7",        "end",          /* terminfo */
+  "@1", "begin",       /* terminfo */
+  "*6", "select",      /* terminfo */
+  "%9", "print",       /* terminfo */
+  "@4", "execute",     /* terminfo --- actually the `command' key */
+  /*
+   * "insert" --- see below
+   */
+  "&8",        "undo",         /* terminfo */
+  "%0",        "redo",         /* terminfo */
+  "%7",        "menu",         /* terminfo --- actually the `options' key */
+  "@0",        "find",         /* terminfo */
+  "@2",        "cancel",       /* terminfo */
+  "%1", "help",                /* terminfo */
+  /*
+   * "break" goes here, but can't be reliably intercepted with termcap
+   */
+  "&4", "reset",       /* terminfo --- actually `restart' */
+  /*
+   * "system" and "user" --- no termcaps
+   */
+  "kE", "clearline",   /* terminfo */
+  "kA", "insertline",  /* terminfo */
+  "kL", "deleteline",  /* terminfo */
+  "kI", "insertchar",  /* terminfo */
+  "kD", "deletechar",  /* terminfo */
+  "kB", "backtab",     /* terminfo */
+  /*
+   * "kp_backtab", "kp-space", "kp-tab" --- no termcaps
+   */
+  "@8", "kp-enter",    /* terminfo */
+  /*
+   * "kp-f1", "kp-f2", "kp-f3" "kp-f4",
+   * "kp-multiply", "kp-add", "kp-separator",
+   * "kp-subtract", "kp-decimal", "kp-divide", "kp-0";
+   * --- no termcaps for any of these.
+   */
+  "K4", "kp-1",                /* terminfo */
+  /*
+   * "kp-2" --- no termcap
+   */
+  "K5", "kp-3",                /* terminfo */
+  /*
+   * "kp-4" --- no termcap
+   */
+  "K2", "kp-5",                /* terminfo */
+  /*
+   * "kp-6" --- no termcap
+   */
+  "K1", "kp-7",                /* terminfo */
+  /*
+   * "kp-8" --- no termcap
+   */
+  "K3", "kp-9",                /* terminfo */
+  /*
+   * "kp-equal" --- no termcap
+   */
+  "k1",        "f1",
+  "k2",        "f2",
+  "k3",        "f3",
+  "k4",        "f4",
+  "k5",        "f5",
+  "k6",        "f6",
+  "k7",        "f7",
+  "k8",        "f8",
+  "k9",        "f9",
   };
 
+static char **term_get_fkeys_arg;
+static Lisp_Object term_get_fkeys_1 ();
+
+/* Find the escape codes sent by the function keys for Vfunction_key_map.
+   This function scans the termcap function key sequence entries, and 
+   adds entries to Vfunction_key_map for each function key it finds.  */
+
 void
 term_get_fkeys (address)
      char **address;
 {
-  extern char *tgetstr ();
+  /* We run the body of the function (term_get_fkeys_1) and ignore all Lisp
+     errors during the call.  The only errors should be from Fdefine_key
+     when given a key sequence containing an invalid prefix key.  If the
+     termcap defines function keys which use a prefix that is already bound
+     to a command by the default bindings, we should silently ignore that
+     function key specification, rather than giving the user an error and
+     refusing to run at all on such a terminal.  */
+
+  extern Lisp_Object Fidentity ();
+  term_get_fkeys_arg = address;
+  internal_condition_case (term_get_fkeys_1, Qerror, Fidentity);
+}
+
+static Lisp_Object
+term_get_fkeys_1 ()
+{
   int i;
 
+  char **address = term_get_fkeys_arg;
+
+  /* This can happen if CANNOT_DUMP or with strange options.  */
+  if (!initialized)
+    Vfunction_key_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 (Vfunction_key_map,
-                    build_string (sequence),
-                    Fmake_vector (make_number (1), intern (keys[i].name)));
+       Fdefine_key (Vfunction_key_map, build_string (sequence),
+                    Fmake_vector (make_number (1),
+                                  intern (keys[i].name)));
     }
 
   /* The uses of the "k0" capability are inconsistent; sometimes it
      describes F10, whereas othertimes it describes F0 and "k;" describes F10.
-     We will attempt to politely accomodate both systems by testing for
+     We will attempt to politely accommodate both systems by testing for
      "k;", and if it is present, assuming that "k0" denotes F0, otherwise F10.
      */
   {
@@ -1211,17 +1303,77 @@ term_get_fkeys (address)
 
     if (k_semi)
       {
-       Fdefine_key (Vfunction_key_map,
-                    build_string (k_semi),
+       Fdefine_key (Vfunction_key_map, build_string (k_semi),
                     Fmake_vector (make_number (1), intern ("f10")));
        k0_name = "f0";
       }
 
     if (k0)
-      Fdefine_key (Vfunction_key_map,
-                  build_string (k0),
+      Fdefine_key (Vfunction_key_map, build_string (k0),
                   Fmake_vector (make_number (1), intern (k0_name)));
   }
+
+  /* Set up cookies for numbered function keys above f10. */
+  {
+    char fcap[3], fkey[4];
+
+    fcap[0] = 'F'; fcap[2] = '\0';
+    for (i = 11; i < 64; i++)
+      {
+       if (i <= 19)
+         fcap[1] = '1' + i - 11;
+       else if (i <= 45)
+         fcap[1] = 'A' + i - 11;
+       else
+         fcap[1] = 'a' + i - 11;
+
+       {
+         char *sequence = tgetstr (fcap, address);
+         if (sequence)
+           {
+             sprintf (fkey, "f%d", i);
+             Fdefine_key (Vfunction_key_map, build_string (sequence),
+                          Fmake_vector (make_number (1),
+                                        intern (fkey)));
+           }
+       }
+      }
+   }
+
+  /*
+   * Various mappings to try and get a better fit.
+   */
+  {
+#define CONDITIONAL_REASSIGN(cap1, cap2, sym)                          \
+      if (!tgetstr (cap1, address))                                    \
+       {                                                               \
+         char *sequence = tgetstr (cap2, address);                     \
+         if (sequence)                                                 \
+           Fdefine_key (Vfunction_key_map, build_string (sequence),    \
+                        Fmake_vector (make_number (1), \
+                                      intern (sym)));  \
+       }
+         
+      /* if there's no key_next keycap, map key_npage to `next' keysym */
+      CONDITIONAL_REASSIGN ("%5", "kN", "next");
+      /* if there's no key_prev keycap, map key_ppage to `previous' keysym */
+      CONDITIONAL_REASSIGN ("%8", "kP", "prior");
+      /* if there's no key_dc keycap, map key_ic to `insert' keysym */
+      CONDITIONAL_REASSIGN ("kD", "kI", "insert");
+
+      /* IBM has their own non-standard dialect of terminfo.
+        If the standard name isn't found, try the IBM name.  */
+      CONDITIONAL_REASSIGN ("kB", "KO", "backtab");
+      CONDITIONAL_REASSIGN ("@4", "kJ", "execute"); /* actually "action" */
+      CONDITIONAL_REASSIGN ("@4", "kc", "execute"); /* actually "command" */
+      CONDITIONAL_REASSIGN ("%7", "ki", "menu");
+      CONDITIONAL_REASSIGN ("@7", "kw", "end");
+      CONDITIONAL_REASSIGN ("F1", "k<", "f11");
+      CONDITIONAL_REASSIGN ("F2", "k>", "f12");
+      CONDITIONAL_REASSIGN ("%1", "kq", "help");
+      CONDITIONAL_REASSIGN ("*6", "kU", "select");
+#undef CONDITIONAL_REASSIGN
+  }
 }
 
 \f
@@ -1234,16 +1386,53 @@ term_init (terminal_type)
   register char *p;
   int status;
 
-  extern char *tgetstr ();
+#ifdef WINDOWSNT
+  initialize_win_nt_display ();
+
+  Wcm_clear ();
+
+  area = (char *) malloc (2044);
+
+  if (area == 0)
+    abort ();
+
+  FrameRows = FRAME_HEIGHT (selected_frame);
+  FrameCols = FRAME_WIDTH (selected_frame);
+  specified_window = FRAME_HEIGHT (selected_frame);
+
+  delete_in_insert_mode = 1;
+
+  UseTabs = 0;
+  scroll_region_ok = 0;
+
+  /* Seems to insert lines when it's not supposed to, messing
+     up the display.  In doing a trace, it didn't seem to be
+     called much, so I don't think we're losing anything by
+     turning it off.  */
+
+  line_ins_del_ok = 0;
+  char_ins_del_ok = 1;
+
+  baud_rate = 19200;
+
+  FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
+  FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
+
+  return;
+#endif /* WINDOWSNT */
 
   Wcm_clear ();
-  dont_calculate_costs = 0;
 
   status = tgetent (buffer, terminal_type);
   if (status < 0)
     fatal ("Cannot open termcap database file.\n");
   if (status == 0)
-    fatal ("Terminal type %s is not defined.\n", terminal_type);
+    fatal ("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\
+to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
+          terminal_type);
 
 #ifdef TERMINFO
   area = (char *) malloc (2044);
@@ -1338,6 +1527,11 @@ term_init (terminal_type)
   if (FRAME_HEIGHT (selected_frame) <= 0)
     FRAME_HEIGHT (selected_frame) = tgetnum ("li");
 
+  if (FRAME_HEIGHT (selected_frame) < 3
+      || FRAME_WIDTH (selected_frame) < 3)
+    fatal ("Screen size %dx%d is too small.\n",
+          FRAME_HEIGHT (selected_frame), FRAME_WIDTH (selected_frame));
+
   min_padding_speed = tgetnum ("pb");
   TN_standout_width = tgetnum ("sg");
   TabWidth = tgetnum ("tw");
@@ -1375,6 +1569,17 @@ term_init (terminal_type)
       TS_standout_mode = tgetstr ("us", address);
     }
 
+  /* If no `se' string, try using a `me' string instead.
+     If that fails, we can't use standout mode at all.  */
+  if (TS_end_standout_mode == 0)
+    {
+      char *s = tgetstr ("me", address);
+      if (s != 0)
+       TS_end_standout_mode = s;
+      else
+       TS_standout_mode = 0;
+    }
+
   if (TF_teleray)
     {
       Wcm.cm_tab = 0;
@@ -1454,8 +1659,9 @@ or `define EMACS_TERM \"terminal type\"' for non-DEC terminals.\n",
     fatal ("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 C-shell command `setenv TERM ...' to specify the correct type.\n\
-It may be necessary to do `unsetenv TERMCAP' as well.\n",
+use the Bourne shell command `TERM=... export TERM' (C-shell:\n\
+`setenv TERM ...') to specify the correct type.  It may be necessary\n\
+to do `unset TERMCAP' (C-shell: `unsetenv TERMCAP') as well.\n",
           terminal_type);
 #endif
   if (FRAME_HEIGHT (selected_frame) <= 0
@@ -1495,8 +1701,8 @@ It may be necessary to do `unsetenv TERMCAP' as well.\n",
                                /* meaningless in this case */
     baud_rate = 9600;
 
-  FRAME_CAN_HAVE_SCROLLBARS (selected_frame) = 0;
-  FRAME_HAS_VERTICAL_SCROLLBARS (selected_frame) = 0;
+  FRAME_CAN_HAVE_SCROLL_BARS (selected_frame) = 0;
+  FRAME_HAS_VERTICAL_SCROLL_BARS (selected_frame) = 0;
 }
 
 /* VARARGS 1 */
@@ -1508,3 +1714,15 @@ fatal (str, arg1, arg2)
   fflush (stderr);
   exit (1);
 }
+
+syms_of_term ()
+{
+  DEFVAR_BOOL ("system-uses-terminfo", &system_uses_terminfo,
+    "Non-nil means the system uses terminfo rather than termcap.\n\
+This variable can be used by terminal emulator packages.");
+#ifdef TERMINFO
+  system_uses_terminfo = 1;
+#else
+  system_uses_terminfo = 0;
+#endif
+}