11acd27e7Smillert /* terminal.c -- controlling the terminal with termcap. */
21acd27e7Smillert
31acd27e7Smillert /* Copyright (C) 1996 Free Software Foundation, Inc.
41acd27e7Smillert
51acd27e7Smillert This file is part of the GNU Readline Library, a library for
61acd27e7Smillert reading lines of text with interactive input and history editing.
71acd27e7Smillert
81acd27e7Smillert The GNU Readline Library is free software; you can redistribute it
91acd27e7Smillert and/or modify it under the terms of the GNU General Public License
101acd27e7Smillert as published by the Free Software Foundation; either version 2, or
111acd27e7Smillert (at your option) any later version.
121acd27e7Smillert
131acd27e7Smillert The GNU Readline Library is distributed in the hope that it will be
141acd27e7Smillert useful, but WITHOUT ANY WARRANTY; without even the implied warranty
151acd27e7Smillert of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
161acd27e7Smillert GNU General Public License for more details.
171acd27e7Smillert
181acd27e7Smillert The GNU General Public License is often shipped with GNU software, and
191acd27e7Smillert is generally kept in a file called COPYING or LICENSE. If you do not
201acd27e7Smillert have a copy of the license, write to the Free Software Foundation,
211acd27e7Smillert 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
221acd27e7Smillert #define READLINE_LIBRARY
231acd27e7Smillert
241acd27e7Smillert #if defined (HAVE_CONFIG_H)
251acd27e7Smillert # include <config.h>
261acd27e7Smillert #endif
271acd27e7Smillert
281acd27e7Smillert #include <sys/types.h>
291acd27e7Smillert #include "posixstat.h"
301acd27e7Smillert #include <fcntl.h>
311acd27e7Smillert #if defined (HAVE_SYS_FILE_H)
321acd27e7Smillert # include <sys/file.h>
331acd27e7Smillert #endif /* HAVE_SYS_FILE_H */
341acd27e7Smillert
351acd27e7Smillert #if defined (HAVE_UNISTD_H)
361acd27e7Smillert # include <unistd.h>
371acd27e7Smillert #endif /* HAVE_UNISTD_H */
381acd27e7Smillert
391acd27e7Smillert #if defined (HAVE_STDLIB_H)
401acd27e7Smillert # include <stdlib.h>
411acd27e7Smillert #else
421acd27e7Smillert # include "ansi_stdlib.h"
431acd27e7Smillert #endif /* HAVE_STDLIB_H */
441acd27e7Smillert
451acd27e7Smillert #if defined (HAVE_LOCALE_H)
461acd27e7Smillert # include <locale.h>
471acd27e7Smillert #endif
481acd27e7Smillert
491acd27e7Smillert #include <stdio.h>
501acd27e7Smillert
511acd27e7Smillert /* System-specific feature definitions and include files. */
521acd27e7Smillert #include "rldefs.h"
531acd27e7Smillert
541acd27e7Smillert # include <sys/ioctl.h>
551acd27e7Smillert
561acd27e7Smillert #include "rltty.h"
571acd27e7Smillert #include "tcap.h"
581acd27e7Smillert
591acd27e7Smillert /* Some standard library routines. */
601acd27e7Smillert #include "readline.h"
611acd27e7Smillert #include "history.h"
621acd27e7Smillert
631acd27e7Smillert #include "rlprivate.h"
641acd27e7Smillert #include "rlshell.h"
65*af70c2dfSkettenis #include "xmalloc.h"
66*af70c2dfSkettenis
67*af70c2dfSkettenis #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
68*af70c2dfSkettenis #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
691acd27e7Smillert
701acd27e7Smillert /* **************************************************************** */
711acd27e7Smillert /* */
721acd27e7Smillert /* Terminal and Termcap */
731acd27e7Smillert /* */
741acd27e7Smillert /* **************************************************************** */
751acd27e7Smillert
761acd27e7Smillert static char *term_buffer = (char *)NULL;
771acd27e7Smillert static char *term_string_buffer = (char *)NULL;
781acd27e7Smillert
791acd27e7Smillert static int tcap_initialized;
801acd27e7Smillert
811acd27e7Smillert #if !defined (__linux__)
821acd27e7Smillert # if defined (__EMX__) || defined (NEED_EXTERN_PC)
831acd27e7Smillert extern
841acd27e7Smillert # endif /* __EMX__ || NEED_EXTERN_PC */
851acd27e7Smillert char PC, *BC, *UP;
861acd27e7Smillert #endif /* __linux__ */
871acd27e7Smillert
881acd27e7Smillert /* Some strings to control terminal actions. These are output by tputs (). */
89*af70c2dfSkettenis char *_rl_term_clreol;
90*af70c2dfSkettenis char *_rl_term_clrpag;
91*af70c2dfSkettenis char *_rl_term_cr;
92*af70c2dfSkettenis char *_rl_term_backspace;
93*af70c2dfSkettenis char *_rl_term_goto;
94*af70c2dfSkettenis char *_rl_term_pc;
951acd27e7Smillert
961acd27e7Smillert /* Non-zero if we determine that the terminal can do character insertion. */
97*af70c2dfSkettenis int _rl_terminal_can_insert = 0;
981acd27e7Smillert
991acd27e7Smillert /* How to insert characters. */
100*af70c2dfSkettenis char *_rl_term_im;
101*af70c2dfSkettenis char *_rl_term_ei;
102*af70c2dfSkettenis char *_rl_term_ic;
103*af70c2dfSkettenis char *_rl_term_ip;
104*af70c2dfSkettenis char *_rl_term_IC;
1051acd27e7Smillert
1061acd27e7Smillert /* How to delete characters. */
107*af70c2dfSkettenis char *_rl_term_dc;
108*af70c2dfSkettenis char *_rl_term_DC;
1091acd27e7Smillert
1101acd27e7Smillert #if defined (HACK_TERMCAP_MOTION)
111*af70c2dfSkettenis char *_rl_term_forward_char;
1121acd27e7Smillert #endif /* HACK_TERMCAP_MOTION */
1131acd27e7Smillert
1141acd27e7Smillert /* How to go up a line. */
115*af70c2dfSkettenis char *_rl_term_up;
1161acd27e7Smillert
117*af70c2dfSkettenis /* A visible bell; char if the terminal can be made to flash the screen. */
118*af70c2dfSkettenis static char *_rl_visible_bell;
1191acd27e7Smillert
1201acd27e7Smillert /* Non-zero means the terminal can auto-wrap lines. */
1211acd27e7Smillert int _rl_term_autowrap;
1221acd27e7Smillert
1231acd27e7Smillert /* Non-zero means that this terminal has a meta key. */
1241acd27e7Smillert static int term_has_meta;
1251acd27e7Smillert
1261acd27e7Smillert /* The sequences to write to turn on and off the meta key, if this
1271acd27e7Smillert terminal has one. */
128*af70c2dfSkettenis static char *_rl_term_mm;
129*af70c2dfSkettenis static char *_rl_term_mo;
1301acd27e7Smillert
1311acd27e7Smillert /* The key sequences output by the arrow keys, if this terminal has any. */
132*af70c2dfSkettenis static char *_rl_term_ku;
133*af70c2dfSkettenis static char *_rl_term_kd;
134*af70c2dfSkettenis static char *_rl_term_kr;
135*af70c2dfSkettenis static char *_rl_term_kl;
1361acd27e7Smillert
1371acd27e7Smillert /* How to initialize and reset the arrow keys, if this terminal has any. */
138*af70c2dfSkettenis static char *_rl_term_ks;
139*af70c2dfSkettenis static char *_rl_term_ke;
1401acd27e7Smillert
1411acd27e7Smillert /* The key sequences sent by the Home and End keys, if any. */
142*af70c2dfSkettenis static char *_rl_term_kh;
143*af70c2dfSkettenis static char *_rl_term_kH;
144*af70c2dfSkettenis static char *_rl_term_at7; /* @7 */
145*af70c2dfSkettenis
146*af70c2dfSkettenis /* Insert key */
147*af70c2dfSkettenis static char *_rl_term_kI;
148*af70c2dfSkettenis
149*af70c2dfSkettenis /* Cursor control */
150*af70c2dfSkettenis static char *_rl_term_vs; /* very visible */
151*af70c2dfSkettenis static char *_rl_term_ve; /* normal */
152*af70c2dfSkettenis
153*af70c2dfSkettenis static void bind_termcap_arrow_keys PARAMS((Keymap));
1541acd27e7Smillert
1551acd27e7Smillert /* Variables that hold the screen dimensions, used by the display code. */
156*af70c2dfSkettenis int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
1571acd27e7Smillert
1581acd27e7Smillert /* Non-zero means the user wants to enable the keypad. */
1591acd27e7Smillert int _rl_enable_keypad;
1601acd27e7Smillert
1611acd27e7Smillert /* Non-zero means the user wants to enable a meta key. */
1621acd27e7Smillert int _rl_enable_meta = 1;
1631acd27e7Smillert
1641acd27e7Smillert #if defined (__EMX__)
1651acd27e7Smillert static void
_emx_get_screensize(swp,shp)1661acd27e7Smillert _emx_get_screensize (swp, shp)
1671acd27e7Smillert int *swp, *shp;
1681acd27e7Smillert {
1691acd27e7Smillert int sz[2];
1701acd27e7Smillert
1711acd27e7Smillert _scrsize (sz);
1721acd27e7Smillert
1731acd27e7Smillert if (swp)
1741acd27e7Smillert *swp = sz[0];
1751acd27e7Smillert if (shp)
1761acd27e7Smillert *shp = sz[1];
1771acd27e7Smillert }
1781acd27e7Smillert #endif
1791acd27e7Smillert
1801acd27e7Smillert /* Get readline's idea of the screen size. TTY is a file descriptor open
1811acd27e7Smillert to the terminal. If IGNORE_ENV is true, we do not pay attention to the
1821acd27e7Smillert values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
1831acd27e7Smillert non-null serve to check whether or not we have initialized termcap. */
1841acd27e7Smillert void
_rl_get_screen_size(tty,ignore_env)1851acd27e7Smillert _rl_get_screen_size (tty, ignore_env)
1861acd27e7Smillert int tty, ignore_env;
1871acd27e7Smillert {
1881acd27e7Smillert char *ss;
1891acd27e7Smillert #if defined (TIOCGWINSZ)
1901acd27e7Smillert struct winsize window_size;
1911acd27e7Smillert #endif /* TIOCGWINSZ */
1921acd27e7Smillert
1931acd27e7Smillert #if defined (TIOCGWINSZ)
1941acd27e7Smillert if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
1951acd27e7Smillert {
196*af70c2dfSkettenis _rl_screenwidth = (int) window_size.ws_col;
197*af70c2dfSkettenis _rl_screenheight = (int) window_size.ws_row;
1981acd27e7Smillert }
1991acd27e7Smillert #endif /* TIOCGWINSZ */
2001acd27e7Smillert
2011acd27e7Smillert #if defined (__EMX__)
202*af70c2dfSkettenis _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
2031acd27e7Smillert #endif
2041acd27e7Smillert
2051acd27e7Smillert /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
2061acd27e7Smillert is unset. */
207*af70c2dfSkettenis if (_rl_screenwidth <= 0)
2081acd27e7Smillert {
209*af70c2dfSkettenis if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")) && *ss != '\0')
210*af70c2dfSkettenis _rl_screenwidth = atoi (ss);
2111acd27e7Smillert
2121acd27e7Smillert #if !defined (__DJGPP__)
213*af70c2dfSkettenis if (_rl_screenwidth <= 0 && term_string_buffer)
214*af70c2dfSkettenis _rl_screenwidth = tgetnum ("co");
2151acd27e7Smillert #endif
2161acd27e7Smillert }
2171acd27e7Smillert
2181acd27e7Smillert /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
2191acd27e7Smillert is unset. */
220*af70c2dfSkettenis if (_rl_screenheight <= 0)
2211acd27e7Smillert {
222*af70c2dfSkettenis if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")) && *ss != '\0')
223*af70c2dfSkettenis _rl_screenheight = atoi (ss);
2241acd27e7Smillert
2251acd27e7Smillert #if !defined (__DJGPP__)
226*af70c2dfSkettenis if (_rl_screenheight <= 0 && term_string_buffer)
227*af70c2dfSkettenis _rl_screenheight = tgetnum ("li");
2281acd27e7Smillert #endif
2291acd27e7Smillert }
2301acd27e7Smillert
2311acd27e7Smillert /* If all else fails, default to 80x24 terminal. */
232*af70c2dfSkettenis if (_rl_screenwidth <= 1)
233*af70c2dfSkettenis _rl_screenwidth = 80;
2341acd27e7Smillert
235*af70c2dfSkettenis if (_rl_screenheight <= 0)
236*af70c2dfSkettenis _rl_screenheight = 24;
2371acd27e7Smillert
2381acd27e7Smillert /* If we're being compiled as part of bash, set the environment
2391acd27e7Smillert variables $LINES and $COLUMNS to new values. Otherwise, just
2401acd27e7Smillert do a pair of putenv () or setenv () calls. */
241*af70c2dfSkettenis sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
2421acd27e7Smillert
2431acd27e7Smillert if (_rl_term_autowrap == 0)
244*af70c2dfSkettenis _rl_screenwidth--;
2451acd27e7Smillert
246*af70c2dfSkettenis _rl_screenchars = _rl_screenwidth * _rl_screenheight;
2471acd27e7Smillert }
2481acd27e7Smillert
2491acd27e7Smillert void
_rl_set_screen_size(rows,cols)2501acd27e7Smillert _rl_set_screen_size (rows, cols)
2511acd27e7Smillert int rows, cols;
2521acd27e7Smillert {
253*af70c2dfSkettenis if (rows == 0 || cols == 0)
254*af70c2dfSkettenis return;
255*af70c2dfSkettenis
256*af70c2dfSkettenis _rl_screenheight = rows;
257*af70c2dfSkettenis _rl_screenwidth = cols;
2581acd27e7Smillert
2591acd27e7Smillert if (_rl_term_autowrap == 0)
260*af70c2dfSkettenis _rl_screenwidth--;
2611acd27e7Smillert
262*af70c2dfSkettenis _rl_screenchars = _rl_screenwidth * _rl_screenheight;
263*af70c2dfSkettenis }
264*af70c2dfSkettenis
265*af70c2dfSkettenis void
rl_set_screen_size(rows,cols)266*af70c2dfSkettenis rl_set_screen_size (rows, cols)
267*af70c2dfSkettenis int rows, cols;
268*af70c2dfSkettenis {
269*af70c2dfSkettenis _rl_set_screen_size (rows, cols);
270*af70c2dfSkettenis }
271*af70c2dfSkettenis
272*af70c2dfSkettenis void
rl_get_screen_size(rows,cols)273*af70c2dfSkettenis rl_get_screen_size (rows, cols)
274*af70c2dfSkettenis int *rows, *cols;
275*af70c2dfSkettenis {
276*af70c2dfSkettenis if (rows)
277*af70c2dfSkettenis *rows = _rl_screenheight;
278*af70c2dfSkettenis if (cols)
279*af70c2dfSkettenis *cols = _rl_screenwidth;
2801acd27e7Smillert }
2811acd27e7Smillert
2821acd27e7Smillert void
rl_resize_terminal()2831acd27e7Smillert rl_resize_terminal ()
2841acd27e7Smillert {
2851acd27e7Smillert if (readline_echoing_p)
2861acd27e7Smillert {
2871acd27e7Smillert _rl_get_screen_size (fileno (rl_instream), 1);
288*af70c2dfSkettenis if (CUSTOM_REDISPLAY_FUNC ())
289*af70c2dfSkettenis rl_forced_update_display ();
290*af70c2dfSkettenis else
2911acd27e7Smillert _rl_redisplay_after_sigwinch ();
2921acd27e7Smillert }
2931acd27e7Smillert }
2941acd27e7Smillert
2951acd27e7Smillert struct _tc_string {
296*af70c2dfSkettenis const char *tc_var;
2971acd27e7Smillert char **tc_value;
2981acd27e7Smillert };
2991acd27e7Smillert
3001acd27e7Smillert /* This should be kept sorted, just in case we decide to change the
3011acd27e7Smillert search algorithm to something smarter. */
3021acd27e7Smillert static struct _tc_string tc_strings[] =
3031acd27e7Smillert {
304*af70c2dfSkettenis { "@7", &_rl_term_at7 },
305*af70c2dfSkettenis { "DC", &_rl_term_DC },
306*af70c2dfSkettenis { "IC", &_rl_term_IC },
307*af70c2dfSkettenis { "ce", &_rl_term_clreol },
308*af70c2dfSkettenis { "cl", &_rl_term_clrpag },
309*af70c2dfSkettenis { "cr", &_rl_term_cr },
310*af70c2dfSkettenis { "dc", &_rl_term_dc },
311*af70c2dfSkettenis { "ei", &_rl_term_ei },
312*af70c2dfSkettenis { "ic", &_rl_term_ic },
313*af70c2dfSkettenis { "im", &_rl_term_im },
314*af70c2dfSkettenis { "kH", &_rl_term_kH }, /* home down ?? */
315*af70c2dfSkettenis { "kI", &_rl_term_kI }, /* insert */
316*af70c2dfSkettenis { "kd", &_rl_term_kd },
317*af70c2dfSkettenis { "ke", &_rl_term_ke }, /* end keypad mode */
318*af70c2dfSkettenis { "kh", &_rl_term_kh }, /* home */
319*af70c2dfSkettenis { "kl", &_rl_term_kl },
320*af70c2dfSkettenis { "kr", &_rl_term_kr },
321*af70c2dfSkettenis { "ks", &_rl_term_ks }, /* start keypad mode */
322*af70c2dfSkettenis { "ku", &_rl_term_ku },
323*af70c2dfSkettenis { "le", &_rl_term_backspace },
324*af70c2dfSkettenis { "mm", &_rl_term_mm },
325*af70c2dfSkettenis { "mo", &_rl_term_mo },
3261acd27e7Smillert #if defined (HACK_TERMCAP_MOTION)
327*af70c2dfSkettenis { "nd", &_rl_term_forward_char },
3281acd27e7Smillert #endif
329*af70c2dfSkettenis { "pc", &_rl_term_pc },
330*af70c2dfSkettenis { "up", &_rl_term_up },
331*af70c2dfSkettenis { "vb", &_rl_visible_bell },
332*af70c2dfSkettenis { "vs", &_rl_term_vs },
333*af70c2dfSkettenis { "ve", &_rl_term_ve },
3341acd27e7Smillert };
3351acd27e7Smillert
3361acd27e7Smillert #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
3371acd27e7Smillert
3381acd27e7Smillert /* Read the desired terminal capability strings into BP. The capabilities
3391acd27e7Smillert are described in the TC_STRINGS table. */
3401acd27e7Smillert static void
get_term_capabilities(bp)3411acd27e7Smillert get_term_capabilities (bp)
3421acd27e7Smillert char **bp;
3431acd27e7Smillert {
3441acd27e7Smillert #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
3451acd27e7Smillert register int i;
3461acd27e7Smillert
3471acd27e7Smillert for (i = 0; i < NUM_TC_STRINGS; i++)
348*af70c2dfSkettenis # ifdef __LCC__
349*af70c2dfSkettenis *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
350*af70c2dfSkettenis # else
3511acd27e7Smillert *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
3521acd27e7Smillert # endif
353*af70c2dfSkettenis #endif
3541acd27e7Smillert tcap_initialized = 1;
3551acd27e7Smillert }
3561acd27e7Smillert
3571acd27e7Smillert int
_rl_init_terminal_io(terminal_name)3581acd27e7Smillert _rl_init_terminal_io (terminal_name)
359*af70c2dfSkettenis const char *terminal_name;
3601acd27e7Smillert {
361*af70c2dfSkettenis const char *term;
362*af70c2dfSkettenis char *buffer;
3631acd27e7Smillert int tty, tgetent_ret;
3641acd27e7Smillert
365*af70c2dfSkettenis term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
366*af70c2dfSkettenis _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
3671acd27e7Smillert tty = rl_instream ? fileno (rl_instream) : 0;
368*af70c2dfSkettenis _rl_screenwidth = _rl_screenheight = 0;
3691acd27e7Smillert
37094bc1d69Smillert if (term == 0 || *term == '\0')
3711acd27e7Smillert term = "dumb";
3721acd27e7Smillert
3731acd27e7Smillert /* I've separated this out for later work on not calling tgetent at all
3741acd27e7Smillert if the calling application has supplied a custom redisplay function,
3751acd27e7Smillert (and possibly if the application has supplied a custom input function). */
3761acd27e7Smillert if (CUSTOM_REDISPLAY_FUNC())
3771acd27e7Smillert {
3781acd27e7Smillert tgetent_ret = -1;
3791acd27e7Smillert }
3801acd27e7Smillert else
3811acd27e7Smillert {
3821acd27e7Smillert if (term_string_buffer == 0)
383*af70c2dfSkettenis term_string_buffer = (char *)xmalloc(2032);
3841acd27e7Smillert
3851acd27e7Smillert if (term_buffer == 0)
386*af70c2dfSkettenis term_buffer = (char *)xmalloc(4080);
3871acd27e7Smillert
3881acd27e7Smillert buffer = term_string_buffer;
3891acd27e7Smillert
3901acd27e7Smillert tgetent_ret = tgetent (term_buffer, term);
3911acd27e7Smillert }
3921acd27e7Smillert
3931acd27e7Smillert if (tgetent_ret <= 0)
3941acd27e7Smillert {
3951acd27e7Smillert FREE (term_string_buffer);
3961acd27e7Smillert FREE (term_buffer);
3971acd27e7Smillert buffer = term_buffer = term_string_buffer = (char *)NULL;
3981acd27e7Smillert
3991acd27e7Smillert _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
4001acd27e7Smillert
4011acd27e7Smillert #if defined (__EMX__)
402*af70c2dfSkettenis _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
403*af70c2dfSkettenis _rl_screenwidth--;
4041acd27e7Smillert #else /* !__EMX__ */
4051acd27e7Smillert _rl_get_screen_size (tty, 0);
4061acd27e7Smillert #endif /* !__EMX__ */
4071acd27e7Smillert
4081acd27e7Smillert /* Defaults. */
409*af70c2dfSkettenis if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
4101acd27e7Smillert {
411*af70c2dfSkettenis _rl_screenwidth = 79;
412*af70c2dfSkettenis _rl_screenheight = 24;
4131acd27e7Smillert }
4141acd27e7Smillert
4151acd27e7Smillert /* Everything below here is used by the redisplay code (tputs). */
416*af70c2dfSkettenis _rl_screenchars = _rl_screenwidth * _rl_screenheight;
417*af70c2dfSkettenis _rl_term_cr = "\r";
418*af70c2dfSkettenis _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
419*af70c2dfSkettenis _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
420*af70c2dfSkettenis _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
421*af70c2dfSkettenis _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
422*af70c2dfSkettenis _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
423*af70c2dfSkettenis _rl_term_mm = _rl_term_mo = (char *)NULL;
424*af70c2dfSkettenis _rl_term_ve = _rl_term_vs = (char *)NULL;
4251acd27e7Smillert #if defined (HACK_TERMCAP_MOTION)
4261acd27e7Smillert term_forward_char = (char *)NULL;
4271acd27e7Smillert #endif
428*af70c2dfSkettenis _rl_terminal_can_insert = term_has_meta = 0;
4291acd27e7Smillert
4301acd27e7Smillert /* Reasonable defaults for tgoto(). Readline currently only uses
431*af70c2dfSkettenis tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
4321acd27e7Smillert change that later... */
4331acd27e7Smillert PC = '\0';
434*af70c2dfSkettenis BC = _rl_term_backspace = "\b";
435*af70c2dfSkettenis UP = _rl_term_up;
4361acd27e7Smillert
4371acd27e7Smillert return 0;
4381acd27e7Smillert }
4391acd27e7Smillert
4401acd27e7Smillert get_term_capabilities (&buffer);
4411acd27e7Smillert
4421acd27e7Smillert /* Set up the variables that the termcap library expects the application
4431acd27e7Smillert to provide. */
444*af70c2dfSkettenis PC = _rl_term_pc ? *_rl_term_pc : 0;
445*af70c2dfSkettenis BC = _rl_term_backspace;
446*af70c2dfSkettenis UP = _rl_term_up;
4471acd27e7Smillert
448*af70c2dfSkettenis if (!_rl_term_cr)
449*af70c2dfSkettenis _rl_term_cr = "\r";
4501acd27e7Smillert
4511acd27e7Smillert _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
4521acd27e7Smillert
4531acd27e7Smillert _rl_get_screen_size (tty, 0);
4541acd27e7Smillert
4551acd27e7Smillert /* "An application program can assume that the terminal can do
4561acd27e7Smillert character insertion if *any one of* the capabilities `IC',
4571acd27e7Smillert `im', `ic' or `ip' is provided." But we can't do anything if
4581acd27e7Smillert only `ip' is provided, so... */
459*af70c2dfSkettenis _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
4601acd27e7Smillert
4611acd27e7Smillert /* Check to see if this terminal has a meta key and clear the capability
4621acd27e7Smillert variables if there is none. */
4631acd27e7Smillert term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
4641acd27e7Smillert if (!term_has_meta)
465*af70c2dfSkettenis _rl_term_mm = _rl_term_mo = (char *)NULL;
4661acd27e7Smillert
4671acd27e7Smillert /* Attempt to find and bind the arrow keys. Do not override already
4681acd27e7Smillert bound keys in an overzealous attempt, however. */
4691acd27e7Smillert
470*af70c2dfSkettenis bind_termcap_arrow_keys (emacs_standard_keymap);
4711acd27e7Smillert
4721acd27e7Smillert #if defined (VI_MODE)
473*af70c2dfSkettenis bind_termcap_arrow_keys (vi_movement_keymap);
474*af70c2dfSkettenis bind_termcap_arrow_keys (vi_insertion_keymap);
4751acd27e7Smillert #endif /* VI_MODE */
4761acd27e7Smillert
4771acd27e7Smillert return 0;
4781acd27e7Smillert }
4791acd27e7Smillert
480*af70c2dfSkettenis /* Bind the arrow key sequences from the termcap description in MAP. */
481*af70c2dfSkettenis static void
bind_termcap_arrow_keys(map)482*af70c2dfSkettenis bind_termcap_arrow_keys (map)
483*af70c2dfSkettenis Keymap map;
484*af70c2dfSkettenis {
485*af70c2dfSkettenis Keymap xkeymap;
486*af70c2dfSkettenis
487*af70c2dfSkettenis xkeymap = _rl_keymap;
488*af70c2dfSkettenis _rl_keymap = map;
489*af70c2dfSkettenis
490*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
491*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
492*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_kr, rl_forward);
493*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_kl, rl_backward);
494*af70c2dfSkettenis
495*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
496*af70c2dfSkettenis _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
497*af70c2dfSkettenis
498*af70c2dfSkettenis _rl_keymap = xkeymap;
499*af70c2dfSkettenis }
500*af70c2dfSkettenis
5011acd27e7Smillert char *
rl_get_termcap(cap)5021acd27e7Smillert rl_get_termcap (cap)
503*af70c2dfSkettenis const char *cap;
5041acd27e7Smillert {
5051acd27e7Smillert register int i;
5061acd27e7Smillert
5071acd27e7Smillert if (tcap_initialized == 0)
5081acd27e7Smillert return ((char *)NULL);
5091acd27e7Smillert for (i = 0; i < NUM_TC_STRINGS; i++)
5101acd27e7Smillert {
5111acd27e7Smillert if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
5121acd27e7Smillert return *(tc_strings[i].tc_value);
5131acd27e7Smillert }
5141acd27e7Smillert return ((char *)NULL);
5151acd27e7Smillert }
5161acd27e7Smillert
5171acd27e7Smillert /* Re-initialize the terminal considering that the TERM/TERMCAP variable
5181acd27e7Smillert has changed. */
5191acd27e7Smillert int
rl_reset_terminal(terminal_name)5201acd27e7Smillert rl_reset_terminal (terminal_name)
521*af70c2dfSkettenis const char *terminal_name;
5221acd27e7Smillert {
5231acd27e7Smillert _rl_init_terminal_io (terminal_name);
5241acd27e7Smillert return 0;
5251acd27e7Smillert }
5261acd27e7Smillert
5271acd27e7Smillert /* A function for the use of tputs () */
5281acd27e7Smillert #ifdef _MINIX
5291acd27e7Smillert void
_rl_output_character_function(c)5301acd27e7Smillert _rl_output_character_function (c)
5311acd27e7Smillert int c;
5321acd27e7Smillert {
5331acd27e7Smillert putc (c, _rl_out_stream);
5341acd27e7Smillert }
5351acd27e7Smillert #else /* !_MINIX */
5361acd27e7Smillert int
_rl_output_character_function(c)5371acd27e7Smillert _rl_output_character_function (c)
5381acd27e7Smillert int c;
5391acd27e7Smillert {
5401acd27e7Smillert return putc (c, _rl_out_stream);
5411acd27e7Smillert }
5421acd27e7Smillert #endif /* !_MINIX */
5431acd27e7Smillert
5441acd27e7Smillert /* Write COUNT characters from STRING to the output stream. */
5451acd27e7Smillert void
_rl_output_some_chars(string,count)5461acd27e7Smillert _rl_output_some_chars (string, count)
547*af70c2dfSkettenis const char *string;
5481acd27e7Smillert int count;
5491acd27e7Smillert {
5501acd27e7Smillert fwrite (string, 1, count, _rl_out_stream);
5511acd27e7Smillert }
5521acd27e7Smillert
5531acd27e7Smillert /* Move the cursor back. */
5541acd27e7Smillert int
_rl_backspace(count)5551acd27e7Smillert _rl_backspace (count)
5561acd27e7Smillert int count;
5571acd27e7Smillert {
5581acd27e7Smillert register int i;
5591acd27e7Smillert
560*af70c2dfSkettenis if (_rl_term_backspace)
5611acd27e7Smillert for (i = 0; i < count; i++)
562*af70c2dfSkettenis tputs (_rl_term_backspace, 1, _rl_output_character_function);
5631acd27e7Smillert else
5641acd27e7Smillert for (i = 0; i < count; i++)
5651acd27e7Smillert putc ('\b', _rl_out_stream);
5661acd27e7Smillert return 0;
5671acd27e7Smillert }
5681acd27e7Smillert
5691acd27e7Smillert /* Move to the start of the next line. */
5701acd27e7Smillert int
rl_crlf()571*af70c2dfSkettenis rl_crlf ()
5721acd27e7Smillert {
5731acd27e7Smillert #if defined (NEW_TTY_DRIVER)
574*af70c2dfSkettenis if (_rl_term_cr)
575*af70c2dfSkettenis tputs (_rl_term_cr, 1, _rl_output_character_function);
5761acd27e7Smillert #endif /* NEW_TTY_DRIVER */
5771acd27e7Smillert putc ('\n', _rl_out_stream);
5781acd27e7Smillert return 0;
5791acd27e7Smillert }
5801acd27e7Smillert
5811acd27e7Smillert /* Ring the terminal bell. */
5821acd27e7Smillert int
rl_ding()583*af70c2dfSkettenis rl_ding ()
5841acd27e7Smillert {
5851acd27e7Smillert if (readline_echoing_p)
5861acd27e7Smillert {
5871acd27e7Smillert switch (_rl_bell_preference)
5881acd27e7Smillert {
5891acd27e7Smillert case NO_BELL:
5901acd27e7Smillert default:
5911acd27e7Smillert break;
5921acd27e7Smillert case VISIBLE_BELL:
593*af70c2dfSkettenis if (_rl_visible_bell)
5941acd27e7Smillert {
595*af70c2dfSkettenis tputs (_rl_visible_bell, 1, _rl_output_character_function);
5961acd27e7Smillert break;
5971acd27e7Smillert }
5981acd27e7Smillert /* FALLTHROUGH */
5991acd27e7Smillert case AUDIBLE_BELL:
6001acd27e7Smillert fprintf (stderr, "\007");
6011acd27e7Smillert fflush (stderr);
6021acd27e7Smillert break;
6031acd27e7Smillert }
6041acd27e7Smillert return (0);
6051acd27e7Smillert }
6061acd27e7Smillert return (-1);
6071acd27e7Smillert }
6081acd27e7Smillert
6091acd27e7Smillert /* **************************************************************** */
6101acd27e7Smillert /* */
6111acd27e7Smillert /* Controlling the Meta Key and Keypad */
6121acd27e7Smillert /* */
6131acd27e7Smillert /* **************************************************************** */
6141acd27e7Smillert
6151acd27e7Smillert void
_rl_enable_meta_key()6161acd27e7Smillert _rl_enable_meta_key ()
6171acd27e7Smillert {
6181acd27e7Smillert #if !defined (__DJGPP__)
619*af70c2dfSkettenis if (term_has_meta && _rl_term_mm)
620*af70c2dfSkettenis tputs (_rl_term_mm, 1, _rl_output_character_function);
6211acd27e7Smillert #endif
6221acd27e7Smillert }
6231acd27e7Smillert
6241acd27e7Smillert void
_rl_control_keypad(on)6251acd27e7Smillert _rl_control_keypad (on)
6261acd27e7Smillert int on;
6271acd27e7Smillert {
6281acd27e7Smillert #if !defined (__DJGPP__)
629*af70c2dfSkettenis if (on && _rl_term_ks)
630*af70c2dfSkettenis tputs (_rl_term_ks, 1, _rl_output_character_function);
631*af70c2dfSkettenis else if (!on && _rl_term_ke)
632*af70c2dfSkettenis tputs (_rl_term_ke, 1, _rl_output_character_function);
6331acd27e7Smillert #endif
6341acd27e7Smillert }
635*af70c2dfSkettenis
636*af70c2dfSkettenis /* **************************************************************** */
637*af70c2dfSkettenis /* */
638*af70c2dfSkettenis /* Controlling the Cursor */
639*af70c2dfSkettenis /* */
640*af70c2dfSkettenis /* **************************************************************** */
641*af70c2dfSkettenis
642*af70c2dfSkettenis /* Set the cursor appropriately depending on IM, which is one of the
643*af70c2dfSkettenis insert modes (insert or overwrite). Insert mode gets the normal
644*af70c2dfSkettenis cursor. Overwrite mode gets a very visible cursor. Only does
645*af70c2dfSkettenis anything if we have both capabilities. */
646*af70c2dfSkettenis void
_rl_set_cursor(im,force)647*af70c2dfSkettenis _rl_set_cursor (im, force)
648*af70c2dfSkettenis int im, force;
649*af70c2dfSkettenis {
650*af70c2dfSkettenis if (_rl_term_ve && _rl_term_vs)
651*af70c2dfSkettenis {
652*af70c2dfSkettenis if (force || im != rl_insert_mode)
653*af70c2dfSkettenis {
654*af70c2dfSkettenis if (im == RL_IM_OVERWRITE)
655*af70c2dfSkettenis tputs (_rl_term_vs, 1, _rl_output_character_function);
656*af70c2dfSkettenis else
657*af70c2dfSkettenis tputs (_rl_term_ve, 1, _rl_output_character_function);
658*af70c2dfSkettenis }
659*af70c2dfSkettenis }
660*af70c2dfSkettenis }
661