Annotation of embedaddon/readline/terminal.c, revision 1.1.1.2

1.1       misho       1: /* terminal.c -- controlling the terminal with termcap. */
                      2: 
1.1.1.2 ! misho       3: /* Copyright (C) 1996-2017 Free Software Foundation, Inc.
1.1       misho       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"
1.1.1.2 ! misho      59: #if defined (HAVE_SYS_IOCTL_H)
        !            60: #  include <sys/ioctl.h>               /* include for declaration of ioctl */
        !            61: #endif
1.1       misho      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;
1.1.1.2 ! misho     115: char *_rl_term_clrscroll;
1.1       misho     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: 
1.1.1.2 ! misho     135: /* How to move forward a char, non-destructively */
1.1       misho     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: 
1.1.1.2 ! misho     155: /* The sequences to enter and exit standout mode. */
        !           156: static char *_rl_term_so;
        !           157: static char *_rl_term_se;
        !           158: 
1.1       misho     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: 
1.1.1.2 ! misho     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: 
1.1       misho     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
1.1.1.2 ! misho     210: _emx_get_screensize (int *swp, int *shp)
1.1       misho     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
1.1.1.2 ! misho     225: _win_get_screensize (int *swp, int *shp)
1.1       misho     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
1.1.1.2 ! misho     247: _rl_get_screen_size (int tty, int ignore_env)
1.1       misho     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
1.1.1.2 ! misho     337: _rl_set_screen_size (int rows, int cols)
1.1       misho     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
1.1.1.2 ! misho     356: rl_set_screen_size (int rows, int cols)
1.1       misho     357: {
                    358:   _rl_set_screen_size (rows, cols);
                    359: }
                    360: 
                    361: void
1.1.1.2 ! misho     362: rl_get_screen_size (int *rows, int *cols)
1.1       misho     363: {
                    364:   if (rows)
                    365:     *rows = _rl_screenheight;
                    366:   if (cols)
                    367:     *cols = _rl_screenwidth;
                    368: }
                    369: 
                    370: void
1.1.1.2 ! misho     371: rl_reset_screen_size (void)
1.1       misho     372: {
                    373:   _rl_get_screen_size (fileno (rl_instream), 0);
                    374: }
                    375: 
                    376: void
1.1.1.2 ! misho     377: _rl_sigwinch_resize_terminal (void)
1.1       misho     378: {
                    379:   _rl_get_screen_size (fileno (rl_instream), 1);
                    380: }
                    381:        
                    382: void
1.1.1.2 ! misho     383: rl_resize_terminal (void)
1.1       misho     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 },
1.1.1.2 ! misho     406:   { "E3", &_rl_term_clrscroll },
1.1       misho     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 },
1.1.1.2 ! misho     430:   { "se", &_rl_term_se },
        !           431:   { "so", &_rl_term_so },
1.1       misho     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
1.1.1.2 ! misho     443: get_term_capabilities (char **bp)
1.1       misho     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
1.1.1.2 ! misho     455: _rl_init_terminal_io (const char *terminal_name)
1.1       misho     456: {
                    457:   const char *term;
                    458:   char *buffer;
1.1.1.2 ! misho     459:   int tty, tgetent_ret, dumbterm;
1.1       misho     460: 
                    461:   term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
1.1.1.2 ! misho     462:   _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = _rl_term_clrscroll = (char *)NULL;
1.1       misho     463:   tty = rl_instream ? fileno (rl_instream) : 0;
                    464: 
                    465:   if (term == 0)
                    466:     term = "dumb";
                    467: 
1.1.1.2 ! misho     468:   dumbterm = STREQ (term, "dumb");
        !           469: 
1.1       misho     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";
1.1.1.2 ! misho     477:   _rl_term_backspace = (char *)NULL;
1.1       misho     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;
1.1.1.2 ! misho     481:   _rl_term_so = _rl_term_se = (char *)NULL;
1.1       misho     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: 
1.1.1.2 ! misho     508:   if (tgetent_ret != TGETENT_SUCCESS)
1.1       misho     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;
1.1.1.2 ! misho     546:       _rl_term_so = _rl_term_se = (char *)NULL;
1.1       misho     547:       _rl_terminal_can_insert = term_has_meta = 0;
                    548: 
1.1.1.2 ! misho     549:       /* Assume generic unknown terminal can't handle the enable/disable
        !           550:         escape sequences */
        !           551:       _rl_enable_bracketed_paste = 0;
        !           552: 
1.1       misho     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: 
1.1.1.2 ! misho     571:   if (_rl_term_cr == 0)
1.1       misho     572:     _rl_term_cr = "\r";
                    573: 
1.1.1.2 ! misho     574:   _rl_term_autowrap = TGETFLAG ("am") && TGETFLAG ("xn");
1.1       misho     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. */
1.1.1.2 ! misho     589:   term_has_meta = TGETFLAG ("km");
1.1       misho     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: 
1.1.1.2 ! misho     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:     
1.1       misho     609:   return 0;
                    610: }
                    611: 
                    612: /* Bind the arrow key sequences from the termcap description in MAP. */
                    613: static void
1.1.1.2 ! misho     614: bind_termcap_arrow_keys (Keymap map)
1.1       misho     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);
1.1.1.2 ! misho     630:   rl_bind_keyseq_if_unbound (_rl_term_kI, rl_overwrite_mode);  /* Insert */
1.1       misho     631: 
                    632:   _rl_keymap = xkeymap;
                    633: }
                    634: 
                    635: char *
1.1.1.2 ! misho     636: rl_get_termcap (const char *cap)
1.1       misho     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
1.1.1.2 ! misho     653: rl_reset_terminal (const char *terminal_name)
1.1       misho     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
1.1.1.2 ! misho     663: _rl_output_character_function (int c)
1.1       misho     664: {
                    665:   putc (c, _rl_out_stream);
                    666: }
                    667: #else /* !_MINIX */
                    668: int
1.1.1.2 ! misho     669: _rl_output_character_function (int c)
1.1       misho     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
1.1.1.2 ! misho     677: _rl_output_some_chars (const char *string, int count)
1.1       misho     678: {
                    679:   fwrite (string, 1, count, _rl_out_stream);
                    680: }
                    681: 
                    682: /* Move the cursor back. */
                    683: int
1.1.1.2 ! misho     684: _rl_backspace (int count)
1.1       misho     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
1.1.1.2 ! misho     701: rl_crlf (void)
1.1       misho     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: 
1.1.1.2 ! misho     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: 
1.1       misho     721: /* Ring the terminal bell. */
                    722: int
1.1.1.2 ! misho     723: rl_ding (void)
1.1       misho     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: /*                                                                 */
1.1.1.2 ! misho     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: /*                                                                 */
1.1       misho     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
1.1.1.2 ! misho     786: _rl_enable_meta_key (void)
1.1       misho     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
1.1.1.2 ! misho     798: _rl_disable_meta_key (void)
1.1       misho     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
1.1.1.2 ! misho     810: _rl_control_keypad (int on)
1.1       misho     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
1.1.1.2 ! misho     831: _rl_set_cursor (int im, int force)
1.1       misho     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>