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

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

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