File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / readline / terminal.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Mar 17 01:01:01 2021 UTC (3 years, 3 months ago) by misho
Branches: readline, MAIN
CVS tags: v8_2p0, v8_1p0, HEAD
readline 8.1

    1: /* terminal.c -- controlling the terminal with termcap. */
    2: 
    3: /* Copyright (C) 1996-2017 Free Software Foundation, Inc.
    4: 
    5:    This file is part of the GNU Readline Library (Readline), a library
    6:    for reading lines of text with interactive input and history editing.      
    7: 
    8:    Readline is free software: you can redistribute it and/or modify
    9:    it under the terms of the GNU General Public License as published by
   10:    the Free Software Foundation, either version 3 of the License, or
   11:    (at your option) any later version.
   12: 
   13:    Readline is distributed in the hope that it will be useful,
   14:    but WITHOUT ANY WARRANTY; without even the implied warranty of
   15:    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16:    GNU General Public License for more details.
   17: 
   18:    You should have received a copy of the GNU General Public License
   19:    along with Readline.  If not, see <http://www.gnu.org/licenses/>.
   20: */
   21: 
   22: #define READLINE_LIBRARY
   23: 
   24: #if defined (HAVE_CONFIG_H)
   25: #  include <config.h>
   26: #endif
   27: 
   28: #include <sys/types.h>
   29: #include "posixstat.h"
   30: #include <fcntl.h>
   31: #if defined (HAVE_SYS_FILE_H)
   32: #  include <sys/file.h>
   33: #endif /* HAVE_SYS_FILE_H */
   34: 
   35: #if defined (HAVE_UNISTD_H)
   36: #  include <unistd.h>
   37: #endif /* HAVE_UNISTD_H */
   38: 
   39: #if defined (HAVE_STDLIB_H)
   40: #  include <stdlib.h>
   41: #else
   42: #  include "ansi_stdlib.h"
   43: #endif /* HAVE_STDLIB_H */
   44: 
   45: #if defined (HAVE_LOCALE_H)
   46: #  include <locale.h>
   47: #endif
   48: 
   49: #include <stdio.h>
   50: 
   51: /* System-specific feature definitions and include files. */
   52: #include "rldefs.h"
   53: 
   54: #ifdef __MSDOS__
   55: #  include <pc.h>
   56: #endif
   57: 
   58: #include "rltty.h"
   59: #if defined (HAVE_SYS_IOCTL_H)
   60: #  include <sys/ioctl.h>		/* include for declaration of ioctl */
   61: #endif
   62: #include "tcap.h"
   63: 
   64: /* Some standard library routines. */
   65: #include "readline.h"
   66: #include "history.h"
   67: 
   68: #include "rlprivate.h"
   69: #include "rlshell.h"
   70: #include "xmalloc.h"
   71: 
   72: #if defined (__MINGW32__)
   73: #  include <windows.h>
   74: #  include <wincon.h>
   75: 
   76: static void _win_get_screensize PARAMS((int *, int *));
   77: #endif
   78: 
   79: #if defined (__EMX__)
   80: static void _emx_get_screensize PARAMS((int *, int *));
   81: #endif
   82: 
   83: /* If the calling application sets this to a non-zero value, readline will
   84:    use the $LINES and $COLUMNS environment variables to set its idea of the
   85:    window size before interrogating the kernel. */
   86: int rl_prefer_env_winsize = 0;
   87: 
   88: /* If this is non-zero, readline will set LINES and COLUMNS in the
   89:    environment when it handles SIGWINCH. */
   90: int rl_change_environment = 1;
   91: 
   92: /* **************************************************************** */
   93: /*								    */
   94: /*			Terminal and Termcap			    */
   95: /*								    */
   96: /* **************************************************************** */
   97: 
   98: #ifndef __MSDOS__
   99: static char *term_buffer = (char *)NULL;
  100: static char *term_string_buffer = (char *)NULL;
  101: #endif
  102: 
  103: static int tcap_initialized;
  104: 
  105: #if !defined (__linux__) && !defined (NCURSES_VERSION)
  106: #  if defined (__EMX__) || defined (NEED_EXTERN_PC)
  107: extern 
  108: #  endif /* __EMX__ || NEED_EXTERN_PC */
  109: char PC, *BC, *UP;
  110: #endif /* !__linux__ && !NCURSES_VERSION */
  111: 
  112: /* Some strings to control terminal actions.  These are output by tputs (). */
  113: char *_rl_term_clreol;
  114: char *_rl_term_clrpag;
  115: char *_rl_term_clrscroll;
  116: char *_rl_term_cr;
  117: char *_rl_term_backspace;
  118: char *_rl_term_goto;
  119: char *_rl_term_pc;
  120: 
  121: /* Non-zero if we determine that the terminal can do character insertion. */
  122: int _rl_terminal_can_insert = 0;
  123: 
  124: /* How to insert characters. */
  125: char *_rl_term_im;
  126: char *_rl_term_ei;
  127: char *_rl_term_ic;
  128: char *_rl_term_ip;
  129: char *_rl_term_IC;
  130: 
  131: /* How to delete characters. */
  132: char *_rl_term_dc;
  133: char *_rl_term_DC;
  134: 
  135: /* How to move forward a char, non-destructively */
  136: char *_rl_term_forward_char;
  137: 
  138: /* How to go up a line. */
  139: char *_rl_term_up;
  140: 
  141: /* A visible bell; char if the terminal can be made to flash the screen. */
  142: static char *_rl_visible_bell;
  143: 
  144: /* Non-zero means the terminal can auto-wrap lines. */
  145: int _rl_term_autowrap = -1;
  146: 
  147: /* Non-zero means that this terminal has a meta key. */
  148: static int term_has_meta;
  149: 
  150: /* The sequences to write to turn on and off the meta key, if this
  151:    terminal has one. */
  152: static char *_rl_term_mm;
  153: static char *_rl_term_mo;
  154: 
  155: /* The sequences to enter and exit standout mode. */
  156: static char *_rl_term_so;
  157: static char *_rl_term_se;
  158: 
  159: /* The key sequences output by the arrow keys, if this terminal has any. */
  160: static char *_rl_term_ku;
  161: static char *_rl_term_kd;
  162: static char *_rl_term_kr;
  163: static char *_rl_term_kl;
  164: 
  165: /* How to initialize and reset the arrow keys, if this terminal has any. */
  166: static char *_rl_term_ks;
  167: static char *_rl_term_ke;
  168: 
  169: /* The key sequences sent by the Home and End keys, if any. */
  170: static char *_rl_term_kh;
  171: static char *_rl_term_kH;
  172: static char *_rl_term_at7;	/* @7 */
  173: 
  174: /* Delete key */
  175: static char *_rl_term_kD;
  176: 
  177: /* Insert key */
  178: static char *_rl_term_kI;
  179: 
  180: /* Cursor control */
  181: static char *_rl_term_vs;	/* very visible */
  182: static char *_rl_term_ve;	/* normal */
  183: 
  184: /* It's not clear how HPUX is so broken here. */
  185: #ifdef TGETENT_BROKEN
  186: #  define TGETENT_SUCCESS 0
  187: #else
  188: #  define TGETENT_SUCCESS 1
  189: #endif
  190: #ifdef TGETFLAG_BROKEN
  191: #  define TGETFLAG_SUCCESS 0
  192: #else
  193: #  define TGETFLAG_SUCCESS 1
  194: #endif
  195: #define TGETFLAG(cap)	(tgetflag (cap) == TGETFLAG_SUCCESS)
  196: 
  197: static void bind_termcap_arrow_keys PARAMS((Keymap));
  198: 
  199: /* Variables that hold the screen dimensions, used by the display code. */
  200: int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
  201: 
  202: /* Non-zero means the user wants to enable the keypad. */
  203: int _rl_enable_keypad;
  204: 
  205: /* Non-zero means the user wants to enable a meta key. */
  206: int _rl_enable_meta = 1;
  207: 
  208: #if defined (__EMX__)
  209: static void
  210: _emx_get_screensize (int *swp, int *shp)
  211: {
  212:   int sz[2];
  213: 
  214:   _scrsize (sz);
  215: 
  216:   if (swp)
  217:     *swp = sz[0];
  218:   if (shp)
  219:     *shp = sz[1];
  220: }
  221: #endif
  222: 
  223: #if defined (__MINGW32__)
  224: static void
  225: _win_get_screensize (int *swp, int *shp)
  226: {
  227:   HANDLE hConOut;
  228:   CONSOLE_SCREEN_BUFFER_INFO scr;
  229: 
  230:   hConOut = GetStdHandle (STD_OUTPUT_HANDLE);
  231:   if (hConOut != INVALID_HANDLE_VALUE)
  232:     {
  233:       if (GetConsoleScreenBufferInfo (hConOut, &scr))
  234: 	{
  235: 	  *swp = scr.dwSize.X;
  236: 	  *shp = scr.srWindow.Bottom - scr.srWindow.Top + 1;
  237: 	}
  238:     }
  239: }
  240: #endif
  241: 
  242: /* Get readline's idea of the screen size.  TTY is a file descriptor open
  243:    to the terminal.  If IGNORE_ENV is true, we do not pay attention to the
  244:    values of $LINES and $COLUMNS.  The tests for TERM_STRING_BUFFER being
  245:    non-null serve to check whether or not we have initialized termcap. */
  246: void
  247: _rl_get_screen_size (int tty, int ignore_env)
  248: {
  249:   char *ss;
  250: #if defined (TIOCGWINSZ)
  251:   struct winsize window_size;
  252: #endif /* TIOCGWINSZ */
  253:   int wr, wc;
  254: 
  255:   wr = wc = -1;
  256: #if defined (TIOCGWINSZ)
  257:   if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
  258:     {
  259:       wc = (int) window_size.ws_col;
  260:       wr = (int) window_size.ws_row;
  261:     }
  262: #endif /* TIOCGWINSZ */
  263: 
  264: #if defined (__EMX__)
  265:   _emx_get_screensize (&wc, &wr);
  266: #elif defined (__MINGW32__)
  267:   _win_get_screensize (&wc, &wr);
  268: #endif
  269: 
  270:   if (ignore_env || rl_prefer_env_winsize == 0)
  271:     {
  272:       _rl_screenwidth = wc;
  273:       _rl_screenheight = wr;
  274:     }
  275:   else
  276:     _rl_screenwidth = _rl_screenheight = -1;
  277: 
  278:   /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
  279:      is unset.  If we prefer the environment, check it first before
  280:      assigning the value returned by the kernel. */
  281:   if (_rl_screenwidth <= 0)
  282:     {
  283:       if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
  284: 	_rl_screenwidth = atoi (ss);
  285: 
  286:       if (_rl_screenwidth <= 0)
  287:         _rl_screenwidth = wc;
  288: 
  289: #if defined (__DJGPP__)
  290:       if (_rl_screenwidth <= 0)
  291: 	_rl_screenwidth = ScreenCols ();
  292: #else
  293:       if (_rl_screenwidth <= 0 && term_string_buffer)
  294: 	_rl_screenwidth = tgetnum ("co");
  295: #endif
  296:     }
  297: 
  298:   /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
  299:      is unset. */
  300:   if (_rl_screenheight <= 0)
  301:     {
  302:       if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
  303: 	_rl_screenheight = atoi (ss);
  304: 
  305:       if (_rl_screenheight <= 0)
  306:         _rl_screenheight = wr;
  307: 
  308: #if defined (__DJGPP__)
  309:       if (_rl_screenheight <= 0)
  310: 	_rl_screenheight = ScreenRows ();
  311: #else
  312:       if (_rl_screenheight <= 0 && term_string_buffer)
  313: 	_rl_screenheight = tgetnum ("li");
  314: #endif
  315:     }
  316: 
  317:   /* If all else fails, default to 80x24 terminal. */
  318:   if (_rl_screenwidth <= 1)
  319:     _rl_screenwidth = 80;
  320: 
  321:   if (_rl_screenheight <= 0)
  322:     _rl_screenheight = 24;
  323: 
  324:   /* If we're being compiled as part of bash, set the environment
  325:      variables $LINES and $COLUMNS to new values.  Otherwise, just
  326:      do a pair of putenv () or setenv () calls. */
  327:   if (rl_change_environment)
  328:     sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
  329: 
  330:   if (_rl_term_autowrap == 0)
  331:     _rl_screenwidth--;
  332: 
  333:   _rl_screenchars = _rl_screenwidth * _rl_screenheight;
  334: }
  335: 
  336: void
  337: _rl_set_screen_size (int rows, int cols)
  338: {
  339:   if (_rl_term_autowrap == -1)
  340:     _rl_init_terminal_io (rl_terminal_name);
  341: 
  342:   if (rows > 0)
  343:     _rl_screenheight = rows;
  344:   if (cols > 0)
  345:     {
  346:       _rl_screenwidth = cols;
  347:       if (_rl_term_autowrap == 0)
  348: 	_rl_screenwidth--;
  349:     }
  350: 
  351:   if (rows > 0 || cols > 0)
  352:     _rl_screenchars = _rl_screenwidth * _rl_screenheight;
  353: }
  354: 
  355: void
  356: rl_set_screen_size (int rows, int cols)
  357: {
  358:   _rl_set_screen_size (rows, cols);
  359: }
  360: 
  361: void
  362: rl_get_screen_size (int *rows, int *cols)
  363: {
  364:   if (rows)
  365:     *rows = _rl_screenheight;
  366:   if (cols)
  367:     *cols = _rl_screenwidth;
  368: }
  369: 
  370: void
  371: rl_reset_screen_size (void)
  372: {
  373:   _rl_get_screen_size (fileno (rl_instream), 0);
  374: }
  375: 
  376: void
  377: _rl_sigwinch_resize_terminal (void)
  378: {
  379:   _rl_get_screen_size (fileno (rl_instream), 1);
  380: }
  381: 	
  382: void
  383: rl_resize_terminal (void)
  384: {
  385:   _rl_get_screen_size (fileno (rl_instream), 1);
  386:   if (_rl_echoing_p)
  387:     {
  388:       if (CUSTOM_REDISPLAY_FUNC ())
  389: 	rl_forced_update_display ();
  390:       else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)
  391: 	_rl_redisplay_after_sigwinch ();
  392:     }
  393: }
  394: 
  395: struct _tc_string {
  396:      const char * const tc_var;
  397:      char **tc_value;
  398: };
  399: 
  400: /* This should be kept sorted, just in case we decide to change the
  401:    search algorithm to something smarter. */
  402: static const struct _tc_string tc_strings[] =
  403: {
  404:   { "@7", &_rl_term_at7 },
  405:   { "DC", &_rl_term_DC },
  406:   { "E3", &_rl_term_clrscroll },
  407:   { "IC", &_rl_term_IC },
  408:   { "ce", &_rl_term_clreol },
  409:   { "cl", &_rl_term_clrpag },
  410:   { "cr", &_rl_term_cr },
  411:   { "dc", &_rl_term_dc },
  412:   { "ei", &_rl_term_ei },
  413:   { "ic", &_rl_term_ic },
  414:   { "im", &_rl_term_im },
  415:   { "kD", &_rl_term_kD },	/* delete */
  416:   { "kH", &_rl_term_kH },	/* home down ?? */
  417:   { "kI", &_rl_term_kI },	/* insert */
  418:   { "kd", &_rl_term_kd },
  419:   { "ke", &_rl_term_ke },	/* end keypad mode */
  420:   { "kh", &_rl_term_kh },	/* home */
  421:   { "kl", &_rl_term_kl },
  422:   { "kr", &_rl_term_kr },
  423:   { "ks", &_rl_term_ks },	/* start keypad mode */
  424:   { "ku", &_rl_term_ku },
  425:   { "le", &_rl_term_backspace },
  426:   { "mm", &_rl_term_mm },
  427:   { "mo", &_rl_term_mo },
  428:   { "nd", &_rl_term_forward_char },
  429:   { "pc", &_rl_term_pc },
  430:   { "se", &_rl_term_se },
  431:   { "so", &_rl_term_so },
  432:   { "up", &_rl_term_up },
  433:   { "vb", &_rl_visible_bell },
  434:   { "vs", &_rl_term_vs },
  435:   { "ve", &_rl_term_ve },
  436: };
  437: 
  438: #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
  439: 
  440: /* Read the desired terminal capability strings into BP.  The capabilities
  441:    are described in the TC_STRINGS table. */
  442: static void
  443: get_term_capabilities (char **bp)
  444: {
  445: #if !defined (__DJGPP__)	/* XXX - doesn't DJGPP have a termcap library? */
  446:   register int i;
  447: 
  448:   for (i = 0; i < NUM_TC_STRINGS; i++)
  449:     *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
  450: #endif
  451:   tcap_initialized = 1;
  452: }
  453: 
  454: int
  455: _rl_init_terminal_io (const char *terminal_name)
  456: {
  457:   const char *term;
  458:   char *buffer;
  459:   int tty, tgetent_ret, dumbterm;
  460: 
  461:   term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
  462:   _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL;
  463:   tty = rl_instream ? fileno (rl_instream) : 0;
  464: 
  465:   if (term == 0)
  466:     term = "dumb";
  467: 
  468:   dumbterm = STREQ (term, "dumb");
  469: 
  470: #ifdef __MSDOS__
  471:   _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
  472:   _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
  473:   _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
  474:   _rl_term_mm = _rl_term_mo = (char *)NULL;
  475:   _rl_terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
  476:   _rl_term_cr = "\r";
  477:   _rl_term_backspace = (char *)NULL;
  478:   _rl_term_goto = _rl_term_pc = _rl_term_ip = (char *)NULL;
  479:   _rl_term_ks = _rl_term_ke =_rl_term_vs = _rl_term_ve = (char *)NULL;
  480:   _rl_term_kh = _rl_term_kH = _rl_term_at7 = _rl_term_kI = (char *)NULL;
  481:   _rl_term_so = _rl_term_se = (char *)NULL;
  482: #if defined(HACK_TERMCAP_MOTION)
  483:   _rl_term_forward_char = (char *)NULL;
  484: #endif
  485: 
  486:   _rl_get_screen_size (tty, 0);
  487: #else  /* !__MSDOS__ */
  488:   /* I've separated this out for later work on not calling tgetent at all
  489:      if the calling application has supplied a custom redisplay function,
  490:      (and possibly if the application has supplied a custom input function). */
  491:   if (CUSTOM_REDISPLAY_FUNC())
  492:     {
  493:       tgetent_ret = -1;
  494:     }
  495:   else
  496:     {
  497:       if (term_string_buffer == 0)
  498: 	term_string_buffer = (char *)xmalloc(2032);
  499: 
  500:       if (term_buffer == 0)
  501: 	term_buffer = (char *)xmalloc(4080);
  502: 
  503:       buffer = term_string_buffer;
  504: 
  505:       tgetent_ret = tgetent (term_buffer, term);
  506:     }
  507: 
  508:   if (tgetent_ret != TGETENT_SUCCESS)
  509:     {
  510:       FREE (term_string_buffer);
  511:       FREE (term_buffer);
  512:       buffer = term_buffer = term_string_buffer = (char *)NULL;
  513: 
  514:       _rl_term_autowrap = 0;	/* used by _rl_get_screen_size */
  515: 
  516:       /* Allow calling application to set default height and width, using
  517: 	 rl_set_screen_size */
  518:       if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
  519: 	{
  520: #if defined (__EMX__)
  521: 	  _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
  522: 	  _rl_screenwidth--;
  523: #else /* !__EMX__ */
  524: 	  _rl_get_screen_size (tty, 0);
  525: #endif /* !__EMX__ */
  526: 	}
  527: 
  528:       /* Defaults. */
  529:       if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
  530:         {
  531: 	  _rl_screenwidth = 79;
  532: 	  _rl_screenheight = 24;
  533:         }
  534: 
  535:       /* Everything below here is used by the redisplay code (tputs). */
  536:       _rl_screenchars = _rl_screenwidth * _rl_screenheight;
  537:       _rl_term_cr = "\r";
  538:       _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
  539:       _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
  540:       _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
  541:       _rl_term_kh = _rl_term_kH = _rl_term_kI = _rl_term_kD = (char *)NULL;
  542:       _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
  543:       _rl_term_mm = _rl_term_mo = (char *)NULL;
  544:       _rl_term_ve = _rl_term_vs = (char *)NULL;
  545:       _rl_term_forward_char = (char *)NULL;
  546:       _rl_term_so = _rl_term_se = (char *)NULL;
  547:       _rl_terminal_can_insert = term_has_meta = 0;
  548: 
  549:       /* Assume generic unknown terminal can't handle the enable/disable
  550: 	 escape sequences */
  551:       _rl_enable_bracketed_paste = 0;
  552: 
  553:       /* Reasonable defaults for tgoto().  Readline currently only uses
  554:          tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
  555:          change that later... */
  556:       PC = '\0';
  557:       BC = _rl_term_backspace = "\b";
  558:       UP = _rl_term_up;
  559: 
  560:       return 0;
  561:     }
  562: 
  563:   get_term_capabilities (&buffer);
  564: 
  565:   /* Set up the variables that the termcap library expects the application
  566:      to provide. */
  567:   PC = _rl_term_pc ? *_rl_term_pc : 0;
  568:   BC = _rl_term_backspace;
  569:   UP = _rl_term_up;
  570: 
  571:   if (_rl_term_cr == 0)
  572:     _rl_term_cr = "\r";
  573: 
  574:   _rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn");
  575: 
  576:   /* Allow calling application to set default height and width, using
  577:      rl_set_screen_size */
  578:   if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
  579:     _rl_get_screen_size (tty, 0);
  580: 
  581:   /* "An application program can assume that the terminal can do
  582:       character insertion if *any one of* the capabilities `IC',
  583:       `im', `ic' or `ip' is provided."  But we can't do anything if
  584:       only `ip' is provided, so... */
  585:   _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
  586: 
  587:   /* Check to see if this terminal has a meta key and clear the capability
  588:      variables if there is none. */
  589:   term_has_meta = TGETFLAG ("km");
  590:   if (term_has_meta == 0)
  591:     _rl_term_mm = _rl_term_mo = (char *)NULL;
  592: #endif /* !__MSDOS__ */
  593: 
  594:   /* Attempt to find and bind the arrow keys.  Do not override already
  595:      bound keys in an overzealous attempt, however. */
  596: 
  597:   bind_termcap_arrow_keys (emacs_standard_keymap);
  598: 
  599: #if defined (VI_MODE)
  600:   bind_termcap_arrow_keys (vi_movement_keymap);
  601:   bind_termcap_arrow_keys (vi_insertion_keymap);
  602: #endif /* VI_MODE */
  603: 
  604:   /* There's no way to determine whether or not a given terminal supports
  605:      bracketed paste mode, so we assume a terminal named "dumb" does not. */
  606:   if (dumbterm)
  607:     _rl_enable_bracketed_paste = 0;
  608:     
  609:   return 0;
  610: }
  611: 
  612: /* Bind the arrow key sequences from the termcap description in MAP. */
  613: static void
  614: bind_termcap_arrow_keys (Keymap map)
  615: {
  616:   Keymap xkeymap;
  617: 
  618:   xkeymap = _rl_keymap;
  619:   _rl_keymap = map;
  620: 
  621:   rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
  622:   rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
  623:   rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
  624:   rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
  625: 
  626:   rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line);	/* Home */
  627:   rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line);	/* End */
  628: 
  629:   rl_bind_keyseq_if_unbound (_rl_term_kD, rl_delete);
  630:   rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode);	/* Insert */
  631: 
  632:   _rl_keymap = xkeymap;
  633: }
  634: 
  635: char *
  636: rl_get_termcap (const char *cap)
  637: {
  638:   register int i;
  639: 
  640:   if (tcap_initialized == 0)
  641:     return ((char *)NULL);
  642:   for (i = 0; i < NUM_TC_STRINGS; i++)
  643:     {
  644:       if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
  645:         return *(tc_strings[i].tc_value);
  646:     }
  647:   return ((char *)NULL);
  648: }
  649: 
  650: /* Re-initialize the terminal considering that the TERM/TERMCAP variable
  651:    has changed. */
  652: int
  653: rl_reset_terminal (const char *terminal_name)
  654: {
  655:   _rl_screenwidth = _rl_screenheight = 0;
  656:   _rl_init_terminal_io (terminal_name);
  657:   return 0;
  658: }
  659: 
  660: /* A function for the use of tputs () */
  661: #ifdef _MINIX
  662: void
  663: _rl_output_character_function (int c)
  664: {
  665:   putc (c, _rl_out_stream);
  666: }
  667: #else /* !_MINIX */
  668: int
  669: _rl_output_character_function (int c)
  670: {
  671:   return putc (c, _rl_out_stream);
  672: }
  673: #endif /* !_MINIX */
  674: 
  675: /* Write COUNT characters from STRING to the output stream. */
  676: void
  677: _rl_output_some_chars (const char *string, int count)
  678: {
  679:   fwrite (string, 1, count, _rl_out_stream);
  680: }
  681: 
  682: /* Move the cursor back. */
  683: int
  684: _rl_backspace (int count)
  685: {
  686:   register int i;
  687: 
  688: #ifndef __MSDOS__
  689:   if (_rl_term_backspace)
  690:     for (i = 0; i < count; i++)
  691:       tputs (_rl_term_backspace, 1, _rl_output_character_function);
  692:   else
  693: #endif
  694:     for (i = 0; i < count; i++)
  695:       putc ('\b', _rl_out_stream);
  696:   return 0;
  697: }
  698: 
  699: /* Move to the start of the next line. */
  700: int
  701: rl_crlf (void)
  702: {
  703: #if defined (NEW_TTY_DRIVER) || defined (__MINT__)
  704:   if (_rl_term_cr)
  705:     tputs (_rl_term_cr, 1, _rl_output_character_function);
  706: #endif /* NEW_TTY_DRIVER || __MINT__ */
  707:   putc ('\n', _rl_out_stream);
  708:   return 0;
  709: }
  710: 
  711: void
  712: _rl_cr (void)
  713: {
  714: #if defined (__MSDOS__)
  715:   putc ('\r', rl_outstream);
  716: #else
  717:   tputs (_rl_term_cr, 1, _rl_output_character_function);
  718: #endif
  719: }
  720: 
  721: /* Ring the terminal bell. */
  722: int
  723: rl_ding (void)
  724: {
  725:   if (_rl_echoing_p)
  726:     {
  727:       switch (_rl_bell_preference)
  728:         {
  729: 	case NO_BELL:
  730: 	default:
  731: 	  break;
  732: 	case VISIBLE_BELL:
  733: 	  if (_rl_visible_bell)
  734: 	    {
  735: #ifdef __DJGPP__
  736: 	      ScreenVisualBell ();
  737: #else
  738: 	      tputs (_rl_visible_bell, 1, _rl_output_character_function);
  739: #endif
  740: 	      break;
  741: 	    }
  742: 	  /* FALLTHROUGH */
  743: 	case AUDIBLE_BELL:
  744: 	  fprintf (stderr, "\007");
  745: 	  fflush (stderr);
  746: 	  break;
  747:         }
  748:       return (0);
  749:     }
  750:   return (-1);
  751: }
  752: 
  753: /* **************************************************************** */
  754: /*								    */
  755: /*		Entering and leaving terminal standout mode	    */
  756: /*								    */
  757: /* **************************************************************** */
  758: 
  759: void
  760: _rl_standout_on (void)
  761: {
  762: #ifndef __MSDOS__
  763:   if (_rl_term_so && _rl_term_se)
  764:     tputs (_rl_term_so, 1, _rl_output_character_function);
  765: #endif
  766: }
  767: 
  768: void
  769: _rl_standout_off (void)
  770: {
  771: #ifndef __MSDOS__
  772:   if (_rl_term_so && _rl_term_se)
  773:     tputs (_rl_term_se, 1, _rl_output_character_function);
  774: #endif
  775: }
  776: 
  777: /* **************************************************************** */
  778: /*								    */
  779: /*	 	Controlling the Meta Key and Keypad		    */
  780: /*								    */
  781: /* **************************************************************** */
  782: 
  783: static int enabled_meta = 0;	/* flag indicating we enabled meta mode */
  784: 
  785: void
  786: _rl_enable_meta_key (void)
  787: {
  788: #if !defined (__DJGPP__)
  789:   if (term_has_meta && _rl_term_mm)
  790:     {
  791:       tputs (_rl_term_mm, 1, _rl_output_character_function);
  792:       enabled_meta = 1;
  793:     }
  794: #endif
  795: }
  796: 
  797: void
  798: _rl_disable_meta_key (void)
  799: {
  800: #if !defined (__DJGPP__)
  801:   if (term_has_meta && _rl_term_mo && enabled_meta)
  802:     {
  803:       tputs (_rl_term_mo, 1, _rl_output_character_function);
  804:       enabled_meta = 0;
  805:     }
  806: #endif
  807: }
  808: 
  809: void
  810: _rl_control_keypad (int on)
  811: {
  812: #if !defined (__DJGPP__)
  813:   if (on && _rl_term_ks)
  814:     tputs (_rl_term_ks, 1, _rl_output_character_function);
  815:   else if (!on && _rl_term_ke)
  816:     tputs (_rl_term_ke, 1, _rl_output_character_function);
  817: #endif
  818: }
  819: 
  820: /* **************************************************************** */
  821: /*								    */
  822: /*	 		Controlling the Cursor			    */
  823: /*								    */
  824: /* **************************************************************** */
  825: 
  826: /* Set the cursor appropriately depending on IM, which is one of the
  827:    insert modes (insert or overwrite).  Insert mode gets the normal
  828:    cursor.  Overwrite mode gets a very visible cursor.  Only does
  829:    anything if we have both capabilities. */
  830: void
  831: _rl_set_cursor (int im, int force)
  832: {
  833: #ifndef __MSDOS__
  834:   if (_rl_term_ve && _rl_term_vs)
  835:     {
  836:       if (force || im != rl_insert_mode)
  837: 	{
  838: 	  if (im == RL_IM_OVERWRITE)
  839: 	    tputs (_rl_term_vs, 1, _rl_output_character_function);
  840: 	  else
  841: 	    tputs (_rl_term_ve, 1, _rl_output_character_function);
  842: 	}
  843:     }
  844: #endif
  845: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>