Deleted Added
full compact
terminal.c (75409) terminal.c (119614)
1/* $FreeBSD: head/contrib/libreadline/terminal.c 75409 2001-04-11 03:15:56Z ache $ */
2/* terminal.c -- controlling the terminal with termcap. */
3
4/* Copyright (C) 1996 Free Software Foundation, Inc.
5
6 This file is part of the GNU Readline Library, a library for
7 reading lines of text with interactive input and history editing.
8
9 The GNU Readline Library is free software; you can redistribute it
10 and/or modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2, or
12 (at your option) any later version.
13
14 The GNU Readline Library is distributed in the hope that it will be
15 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
16 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 The GNU General Public License is often shipped with GNU software, and
20 is generally kept in a file called COPYING or LICENSE. If you do not
21 have a copy of the license, write to the Free Software Foundation,
22 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
1/* terminal.c -- controlling the terminal with termcap. */
2
3/* Copyright (C) 1996 Free Software Foundation, Inc.
4
5 This file is part of the GNU Readline Library, a library for
6 reading lines of text with interactive input and history editing.
7
8 The GNU Readline Library is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2, or
11 (at your option) any later version.
12
13 The GNU Readline Library is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 The GNU General Public License is often shipped with GNU software, and
19 is generally kept in a file called COPYING or LICENSE. If you do not
20 have a copy of the license, write to the Free Software Foundation,
21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
22/* $FreeBSD: head/contrib/libreadline/terminal.c 119614 2003-08-31 18:29:38Z ache $ */
23#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
26# include <config.h>
27#endif
28
29#include <sys/types.h>
30#include "posixstat.h"
31#include <fcntl.h>
32#if defined (HAVE_SYS_FILE_H)
33# include <sys/file.h>
34#endif /* HAVE_SYS_FILE_H */
35
36#if defined (HAVE_UNISTD_H)
37# include <unistd.h>
38#endif /* HAVE_UNISTD_H */
39
40#if defined (HAVE_STDLIB_H)
41# include <stdlib.h>
42#else
43# include "ansi_stdlib.h"
44#endif /* HAVE_STDLIB_H */
45
46#if defined (HAVE_LOCALE_H)
47# include <locale.h>
48#endif
49
50#include <stdio.h>
51
52/* System-specific feature definitions and include files. */
53#include "rldefs.h"
54
55#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
56# include <sys/ioctl.h>
57#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
58
59#include "rltty.h"
60#include "tcap.h"
61
62/* Some standard library routines. */
63#include "readline.h"
64#include "history.h"
65
66#include "rlprivate.h"
67#include "rlshell.h"
23#define READLINE_LIBRARY
24
25#if defined (HAVE_CONFIG_H)
26# include <config.h>
27#endif
28
29#include <sys/types.h>
30#include "posixstat.h"
31#include <fcntl.h>
32#if defined (HAVE_SYS_FILE_H)
33# include <sys/file.h>
34#endif /* HAVE_SYS_FILE_H */
35
36#if defined (HAVE_UNISTD_H)
37# include <unistd.h>
38#endif /* HAVE_UNISTD_H */
39
40#if defined (HAVE_STDLIB_H)
41# include <stdlib.h>
42#else
43# include "ansi_stdlib.h"
44#endif /* HAVE_STDLIB_H */
45
46#if defined (HAVE_LOCALE_H)
47# include <locale.h>
48#endif
49
50#include <stdio.h>
51
52/* System-specific feature definitions and include files. */
53#include "rldefs.h"
54
55#if defined (GWINSZ_IN_SYS_IOCTL) && !defined (TIOCGWINSZ)
56# include <sys/ioctl.h>
57#endif /* GWINSZ_IN_SYS_IOCTL && !TIOCGWINSZ */
58
59#include "rltty.h"
60#include "tcap.h"
61
62/* Some standard library routines. */
63#include "readline.h"
64#include "history.h"
65
66#include "rlprivate.h"
67#include "rlshell.h"
68#include "xmalloc.h"
68
69
70#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
71#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
72
69/* **************************************************************** */
70/* */
71/* Terminal and Termcap */
72/* */
73/* **************************************************************** */
74
75static char *term_buffer = (char *)NULL;
76static char *term_string_buffer = (char *)NULL;
77
78static int tcap_initialized;
79
80#if !defined (__linux__)
81# if defined (__EMX__) || defined (NEED_EXTERN_PC)
82extern
83# endif /* __EMX__ || NEED_EXTERN_PC */
84char PC, *BC, *UP;
85#endif /* __linux__ */
86
87/* Some strings to control terminal actions. These are output by tputs (). */
88char *_rl_term_clreol;
89char *_rl_term_clrpag;
90char *_rl_term_cr;
91char *_rl_term_backspace;
92char *_rl_term_goto;
93char *_rl_term_pc;
94
95/* Non-zero if we determine that the terminal can do character insertion. */
96int _rl_terminal_can_insert = 0;
97
98/* How to insert characters. */
99char *_rl_term_im;
100char *_rl_term_ei;
101char *_rl_term_ic;
102char *_rl_term_ip;
103char *_rl_term_IC;
104
105/* How to delete characters. */
106char *_rl_term_dc;
107char *_rl_term_DC;
108
109#if defined (HACK_TERMCAP_MOTION)
110char *_rl_term_forward_char;
111#endif /* HACK_TERMCAP_MOTION */
112
113/* How to go up a line. */
114char *_rl_term_up;
115
116/* A visible bell; char if the terminal can be made to flash the screen. */
117static char *_rl_visible_bell;
118
119/* Non-zero means the terminal can auto-wrap lines. */
120int _rl_term_autowrap;
121
122/* Non-zero means that this terminal has a meta key. */
123static int term_has_meta;
124
125/* The sequences to write to turn on and off the meta key, if this
126 terminal has one. */
127static char *_rl_term_mm;
128static char *_rl_term_mo;
129
130/* The key sequences output by the arrow keys, if this terminal has any. */
131static char *_rl_term_ku;
132static char *_rl_term_kd;
133static char *_rl_term_kr;
134static char *_rl_term_kl;
135
136/* How to initialize and reset the arrow keys, if this terminal has any. */
137static char *_rl_term_ks;
138static char *_rl_term_ke;
139
140/* The key sequences sent by the Home and End keys, if any. */
141static char *_rl_term_kh;
142static char *_rl_term_kH;
73/* **************************************************************** */
74/* */
75/* Terminal and Termcap */
76/* */
77/* **************************************************************** */
78
79static char *term_buffer = (char *)NULL;
80static char *term_string_buffer = (char *)NULL;
81
82static int tcap_initialized;
83
84#if !defined (__linux__)
85# if defined (__EMX__) || defined (NEED_EXTERN_PC)
86extern
87# endif /* __EMX__ || NEED_EXTERN_PC */
88char PC, *BC, *UP;
89#endif /* __linux__ */
90
91/* Some strings to control terminal actions. These are output by tputs (). */
92char *_rl_term_clreol;
93char *_rl_term_clrpag;
94char *_rl_term_cr;
95char *_rl_term_backspace;
96char *_rl_term_goto;
97char *_rl_term_pc;
98
99/* Non-zero if we determine that the terminal can do character insertion. */
100int _rl_terminal_can_insert = 0;
101
102/* How to insert characters. */
103char *_rl_term_im;
104char *_rl_term_ei;
105char *_rl_term_ic;
106char *_rl_term_ip;
107char *_rl_term_IC;
108
109/* How to delete characters. */
110char *_rl_term_dc;
111char *_rl_term_DC;
112
113#if defined (HACK_TERMCAP_MOTION)
114char *_rl_term_forward_char;
115#endif /* HACK_TERMCAP_MOTION */
116
117/* How to go up a line. */
118char *_rl_term_up;
119
120/* A visible bell; char if the terminal can be made to flash the screen. */
121static char *_rl_visible_bell;
122
123/* Non-zero means the terminal can auto-wrap lines. */
124int _rl_term_autowrap;
125
126/* Non-zero means that this terminal has a meta key. */
127static int term_has_meta;
128
129/* The sequences to write to turn on and off the meta key, if this
130 terminal has one. */
131static char *_rl_term_mm;
132static char *_rl_term_mo;
133
134/* The key sequences output by the arrow keys, if this terminal has any. */
135static char *_rl_term_ku;
136static char *_rl_term_kd;
137static char *_rl_term_kr;
138static char *_rl_term_kl;
139
140/* How to initialize and reset the arrow keys, if this terminal has any. */
141static char *_rl_term_ks;
142static char *_rl_term_ke;
143
144/* The key sequences sent by the Home and End keys, if any. */
145static char *_rl_term_kh;
146static char *_rl_term_kH;
147static char *_rl_term_at7; /* @7 */
143
148
149/* Insert key */
150static char *_rl_term_kI;
151
152/* Cursor control */
153static char *_rl_term_vs; /* very visible */
154static char *_rl_term_ve; /* normal */
155
156static void bind_termcap_arrow_keys PARAMS((Keymap));
157
144/* Variables that hold the screen dimensions, used by the display code. */
145int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
146
147/* Non-zero means the user wants to enable the keypad. */
148int _rl_enable_keypad;
149
150/* Non-zero means the user wants to enable a meta key. */
151int _rl_enable_meta = 1;
152
153#if defined (__EMX__)
154static void
155_emx_get_screensize (swp, shp)
156 int *swp, *shp;
157{
158 int sz[2];
159
160 _scrsize (sz);
161
162 if (swp)
163 *swp = sz[0];
164 if (shp)
165 *shp = sz[1];
166}
167#endif
168
169/* Get readline's idea of the screen size. TTY is a file descriptor open
170 to the terminal. If IGNORE_ENV is true, we do not pay attention to the
171 values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
172 non-null serve to check whether or not we have initialized termcap. */
173void
174_rl_get_screen_size (tty, ignore_env)
175 int tty, ignore_env;
176{
177 char *ss;
178#if defined (TIOCGWINSZ)
179 struct winsize window_size;
180#endif /* TIOCGWINSZ */
181
182#if defined (TIOCGWINSZ)
183 if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
184 {
185 _rl_screenwidth = (int) window_size.ws_col;
186 _rl_screenheight = (int) window_size.ws_row;
187 }
188#endif /* TIOCGWINSZ */
189
190#if defined (__EMX__)
191 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
192#endif
193
194 /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
195 is unset. */
196 if (_rl_screenwidth <= 0)
197 {
198 if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
199 _rl_screenwidth = atoi (ss);
200
201#if !defined (__DJGPP__)
202 if (_rl_screenwidth <= 0 && term_string_buffer)
203 _rl_screenwidth = tgetnum ("co");
204#endif
205 }
206
207 /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
208 is unset. */
209 if (_rl_screenheight <= 0)
210 {
211 if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
212 _rl_screenheight = atoi (ss);
213
214#if !defined (__DJGPP__)
215 if (_rl_screenheight <= 0 && term_string_buffer)
216 _rl_screenheight = tgetnum ("li");
217#endif
218 }
219
220 /* If all else fails, default to 80x24 terminal. */
221 if (_rl_screenwidth <= 1)
222 _rl_screenwidth = 80;
223
224 if (_rl_screenheight <= 0)
225 _rl_screenheight = 24;
226
227 /* If we're being compiled as part of bash, set the environment
228 variables $LINES and $COLUMNS to new values. Otherwise, just
229 do a pair of putenv () or setenv () calls. */
230 sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
231
232 if (_rl_term_autowrap == 0)
233 _rl_screenwidth--;
234
235 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
236}
237
238void
239_rl_set_screen_size (rows, cols)
240 int rows, cols;
241{
242 if (rows == 0 || cols == 0)
243 return;
244
245 _rl_screenheight = rows;
246 _rl_screenwidth = cols;
247
248 if (_rl_term_autowrap == 0)
249 _rl_screenwidth--;
250
251 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
252}
253
254void
255rl_set_screen_size (rows, cols)
256 int rows, cols;
257{
258 _rl_set_screen_size (rows, cols);
259}
260
261void
262rl_get_screen_size (rows, cols)
263 int *rows, *cols;
264{
265 if (rows)
266 *rows = _rl_screenheight;
267 if (cols)
268 *cols = _rl_screenwidth;
269}
270
271void
272rl_resize_terminal ()
273{
274 if (readline_echoing_p)
275 {
276 _rl_get_screen_size (fileno (rl_instream), 1);
158/* Variables that hold the screen dimensions, used by the display code. */
159int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
160
161/* Non-zero means the user wants to enable the keypad. */
162int _rl_enable_keypad;
163
164/* Non-zero means the user wants to enable a meta key. */
165int _rl_enable_meta = 1;
166
167#if defined (__EMX__)
168static void
169_emx_get_screensize (swp, shp)
170 int *swp, *shp;
171{
172 int sz[2];
173
174 _scrsize (sz);
175
176 if (swp)
177 *swp = sz[0];
178 if (shp)
179 *shp = sz[1];
180}
181#endif
182
183/* Get readline's idea of the screen size. TTY is a file descriptor open
184 to the terminal. If IGNORE_ENV is true, we do not pay attention to the
185 values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
186 non-null serve to check whether or not we have initialized termcap. */
187void
188_rl_get_screen_size (tty, ignore_env)
189 int tty, ignore_env;
190{
191 char *ss;
192#if defined (TIOCGWINSZ)
193 struct winsize window_size;
194#endif /* TIOCGWINSZ */
195
196#if defined (TIOCGWINSZ)
197 if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
198 {
199 _rl_screenwidth = (int) window_size.ws_col;
200 _rl_screenheight = (int) window_size.ws_row;
201 }
202#endif /* TIOCGWINSZ */
203
204#if defined (__EMX__)
205 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
206#endif
207
208 /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
209 is unset. */
210 if (_rl_screenwidth <= 0)
211 {
212 if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
213 _rl_screenwidth = atoi (ss);
214
215#if !defined (__DJGPP__)
216 if (_rl_screenwidth <= 0 && term_string_buffer)
217 _rl_screenwidth = tgetnum ("co");
218#endif
219 }
220
221 /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
222 is unset. */
223 if (_rl_screenheight <= 0)
224 {
225 if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
226 _rl_screenheight = atoi (ss);
227
228#if !defined (__DJGPP__)
229 if (_rl_screenheight <= 0 && term_string_buffer)
230 _rl_screenheight = tgetnum ("li");
231#endif
232 }
233
234 /* If all else fails, default to 80x24 terminal. */
235 if (_rl_screenwidth <= 1)
236 _rl_screenwidth = 80;
237
238 if (_rl_screenheight <= 0)
239 _rl_screenheight = 24;
240
241 /* If we're being compiled as part of bash, set the environment
242 variables $LINES and $COLUMNS to new values. Otherwise, just
243 do a pair of putenv () or setenv () calls. */
244 sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
245
246 if (_rl_term_autowrap == 0)
247 _rl_screenwidth--;
248
249 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
250}
251
252void
253_rl_set_screen_size (rows, cols)
254 int rows, cols;
255{
256 if (rows == 0 || cols == 0)
257 return;
258
259 _rl_screenheight = rows;
260 _rl_screenwidth = cols;
261
262 if (_rl_term_autowrap == 0)
263 _rl_screenwidth--;
264
265 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
266}
267
268void
269rl_set_screen_size (rows, cols)
270 int rows, cols;
271{
272 _rl_set_screen_size (rows, cols);
273}
274
275void
276rl_get_screen_size (rows, cols)
277 int *rows, *cols;
278{
279 if (rows)
280 *rows = _rl_screenheight;
281 if (cols)
282 *cols = _rl_screenwidth;
283}
284
285void
286rl_resize_terminal ()
287{
288 if (readline_echoing_p)
289 {
290 _rl_get_screen_size (fileno (rl_instream), 1);
277 _rl_redisplay_after_sigwinch ();
291 if (CUSTOM_REDISPLAY_FUNC ())
292 rl_forced_update_display ();
293 else
294 _rl_redisplay_after_sigwinch ();
278 }
279}
280
281struct _tc_string {
282 const char *tc_var;
283 char **tc_value;
284};
285
286/* This should be kept sorted, just in case we decide to change the
287 search algorithm to something smarter. */
288static struct _tc_string tc_strings[] =
289{
295 }
296}
297
298struct _tc_string {
299 const char *tc_var;
300 char **tc_value;
301};
302
303/* This should be kept sorted, just in case we decide to change the
304 search algorithm to something smarter. */
305static struct _tc_string tc_strings[] =
306{
307 { "@7", &_rl_term_at7 },
290 { "DC", &_rl_term_DC },
291 { "IC", &_rl_term_IC },
292 { "ce", &_rl_term_clreol },
293 { "cl", &_rl_term_clrpag },
294 { "cr", &_rl_term_cr },
295 { "dc", &_rl_term_dc },
296 { "ei", &_rl_term_ei },
297 { "ic", &_rl_term_ic },
298 { "im", &_rl_term_im },
308 { "DC", &_rl_term_DC },
309 { "IC", &_rl_term_IC },
310 { "ce", &_rl_term_clreol },
311 { "cl", &_rl_term_clrpag },
312 { "cr", &_rl_term_cr },
313 { "dc", &_rl_term_dc },
314 { "ei", &_rl_term_ei },
315 { "ic", &_rl_term_ic },
316 { "im", &_rl_term_im },
317 { "kH", &_rl_term_kH }, /* home down ?? */
318 { "kI", &_rl_term_kI }, /* insert */
299 { "kd", &_rl_term_kd },
319 { "kd", &_rl_term_kd },
320 { "ke", &_rl_term_ke }, /* end keypad mode */
300 { "kh", &_rl_term_kh }, /* home */
321 { "kh", &_rl_term_kh }, /* home */
301 { "@7", &_rl_term_kH }, /* end */
302 { "kl", &_rl_term_kl },
303 { "kr", &_rl_term_kr },
322 { "kl", &_rl_term_kl },
323 { "kr", &_rl_term_kr },
324 { "ks", &_rl_term_ks }, /* start keypad mode */
304 { "ku", &_rl_term_ku },
325 { "ku", &_rl_term_ku },
305 { "ks", &_rl_term_ks },
306 { "ke", &_rl_term_ke },
307 { "le", &_rl_term_backspace },
308 { "mm", &_rl_term_mm },
309 { "mo", &_rl_term_mo },
310#if defined (HACK_TERMCAP_MOTION)
311 { "nd", &_rl_term_forward_char },
312#endif
313 { "pc", &_rl_term_pc },
314 { "up", &_rl_term_up },
315 { "vb", &_rl_visible_bell },
326 { "le", &_rl_term_backspace },
327 { "mm", &_rl_term_mm },
328 { "mo", &_rl_term_mo },
329#if defined (HACK_TERMCAP_MOTION)
330 { "nd", &_rl_term_forward_char },
331#endif
332 { "pc", &_rl_term_pc },
333 { "up", &_rl_term_up },
334 { "vb", &_rl_visible_bell },
335 { "vs", &_rl_term_vs },
336 { "ve", &_rl_term_ve },
316};
317
318#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
319
320/* Read the desired terminal capability strings into BP. The capabilities
321 are described in the TC_STRINGS table. */
322static void
323get_term_capabilities (bp)
324 char **bp;
325{
326#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
327 register int i;
328
329 for (i = 0; i < NUM_TC_STRINGS; i++)
337};
338
339#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
340
341/* Read the desired terminal capability strings into BP. The capabilities
342 are described in the TC_STRINGS table. */
343static void
344get_term_capabilities (bp)
345 char **bp;
346{
347#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
348 register int i;
349
350 for (i = 0; i < NUM_TC_STRINGS; i++)
351# ifdef __LCC__
352 *(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
353# else
330 *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
354 *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
355# endif
331#endif
332 tcap_initialized = 1;
333}
334
356#endif
357 tcap_initialized = 1;
358}
359
335#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
336#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
337
338int
339_rl_init_terminal_io (terminal_name)
340 const char *terminal_name;
341{
342 const char *term;
343 char *buffer;
344 int tty, tgetent_ret;
360int
361_rl_init_terminal_io (terminal_name)
362 const char *terminal_name;
363{
364 const char *term;
365 char *buffer;
366 int tty, tgetent_ret;
345 Keymap xkeymap;
346
347 term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
348 _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
349 tty = rl_instream ? fileno (rl_instream) : 0;
350 _rl_screenwidth = _rl_screenheight = 0;
351
352 if (term == 0)
353 term = "dumb";
354
355 /* I've separated this out for later work on not calling tgetent at all
356 if the calling application has supplied a custom redisplay function,
357 (and possibly if the application has supplied a custom input function). */
358 if (CUSTOM_REDISPLAY_FUNC())
359 {
360 tgetent_ret = -1;
361 }
362 else
363 {
364 if (term_string_buffer == 0)
367
368 term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
369 _rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
370 tty = rl_instream ? fileno (rl_instream) : 0;
371 _rl_screenwidth = _rl_screenheight = 0;
372
373 if (term == 0)
374 term = "dumb";
375
376 /* I've separated this out for later work on not calling tgetent at all
377 if the calling application has supplied a custom redisplay function,
378 (and possibly if the application has supplied a custom input function). */
379 if (CUSTOM_REDISPLAY_FUNC())
380 {
381 tgetent_ret = -1;
382 }
383 else
384 {
385 if (term_string_buffer == 0)
365 term_string_buffer = xmalloc(2032);
386 term_string_buffer = (char *)xmalloc(2032);
366
367 if (term_buffer == 0)
387
388 if (term_buffer == 0)
368 term_buffer = xmalloc(4080);
389 term_buffer = (char *)xmalloc(4080);
369
370 buffer = term_string_buffer;
371
372 tgetent_ret = tgetent (term_buffer, term);
373 }
374
375 if (tgetent_ret <= 0)
376 {
377 FREE (term_string_buffer);
378 FREE (term_buffer);
379 buffer = term_buffer = term_string_buffer = (char *)NULL;
380
381 _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
382
383#if defined (__EMX__)
384 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
385 _rl_screenwidth--;
386#else /* !__EMX__ */
387 _rl_get_screen_size (tty, 0);
388#endif /* !__EMX__ */
389
390 /* Defaults. */
391 if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
392 {
393 _rl_screenwidth = 79;
394 _rl_screenheight = 24;
395 }
396
397 /* Everything below here is used by the redisplay code (tputs). */
398 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
399 _rl_term_cr = "\r";
400 _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
401 _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
402 _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
390
391 buffer = term_string_buffer;
392
393 tgetent_ret = tgetent (term_buffer, term);
394 }
395
396 if (tgetent_ret <= 0)
397 {
398 FREE (term_string_buffer);
399 FREE (term_buffer);
400 buffer = term_buffer = term_string_buffer = (char *)NULL;
401
402 _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
403
404#if defined (__EMX__)
405 _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
406 _rl_screenwidth--;
407#else /* !__EMX__ */
408 _rl_get_screen_size (tty, 0);
409#endif /* !__EMX__ */
410
411 /* Defaults. */
412 if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
413 {
414 _rl_screenwidth = 79;
415 _rl_screenheight = 24;
416 }
417
418 /* Everything below here is used by the redisplay code (tputs). */
419 _rl_screenchars = _rl_screenwidth * _rl_screenheight;
420 _rl_term_cr = "\r";
421 _rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
422 _rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
423 _rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
424 _rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
425 _rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
403 _rl_term_mm = _rl_term_mo = (char *)NULL;
426 _rl_term_mm = _rl_term_mo = (char *)NULL;
427 _rl_term_ve = _rl_term_vs = (char *)NULL;
404#if defined (HACK_TERMCAP_MOTION)
405 term_forward_char = (char *)NULL;
406#endif
407 _rl_terminal_can_insert = term_has_meta = 0;
408
409 /* Reasonable defaults for tgoto(). Readline currently only uses
410 tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
411 change that later... */
412 PC = '\0';
413 BC = _rl_term_backspace = "\b";
414 UP = _rl_term_up;
415
416 return 0;
417 }
418
419 get_term_capabilities (&buffer);
420
421 /* Set up the variables that the termcap library expects the application
422 to provide. */
423 PC = _rl_term_pc ? *_rl_term_pc : 0;
424 BC = _rl_term_backspace;
425 UP = _rl_term_up;
426
427 if (!_rl_term_cr)
428 _rl_term_cr = "\r";
429
430 _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
431
432 _rl_get_screen_size (tty, 0);
433
434 /* "An application program can assume that the terminal can do
435 character insertion if *any one of* the capabilities `IC',
436 `im', `ic' or `ip' is provided." But we can't do anything if
437 only `ip' is provided, so... */
438 _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
439
440 /* Check to see if this terminal has a meta key and clear the capability
441 variables if there is none. */
442 term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
443 if (!term_has_meta)
444 _rl_term_mm = _rl_term_mo = (char *)NULL;
445
446 /* Attempt to find and bind the arrow keys. Do not override already
447 bound keys in an overzealous attempt, however. */
428#if defined (HACK_TERMCAP_MOTION)
429 term_forward_char = (char *)NULL;
430#endif
431 _rl_terminal_can_insert = term_has_meta = 0;
432
433 /* Reasonable defaults for tgoto(). Readline currently only uses
434 tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
435 change that later... */
436 PC = '\0';
437 BC = _rl_term_backspace = "\b";
438 UP = _rl_term_up;
439
440 return 0;
441 }
442
443 get_term_capabilities (&buffer);
444
445 /* Set up the variables that the termcap library expects the application
446 to provide. */
447 PC = _rl_term_pc ? *_rl_term_pc : 0;
448 BC = _rl_term_backspace;
449 UP = _rl_term_up;
450
451 if (!_rl_term_cr)
452 _rl_term_cr = "\r";
453
454 _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
455
456 _rl_get_screen_size (tty, 0);
457
458 /* "An application program can assume that the terminal can do
459 character insertion if *any one of* the capabilities `IC',
460 `im', `ic' or `ip' is provided." But we can't do anything if
461 only `ip' is provided, so... */
462 _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
463
464 /* Check to see if this terminal has a meta key and clear the capability
465 variables if there is none. */
466 term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
467 if (!term_has_meta)
468 _rl_term_mm = _rl_term_mo = (char *)NULL;
469
470 /* Attempt to find and bind the arrow keys. Do not override already
471 bound keys in an overzealous attempt, however. */
448 xkeymap = _rl_keymap;
449
472
450 _rl_keymap = emacs_standard_keymap;
451 _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
452 _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
453 _rl_bind_if_unbound (_rl_term_kr, rl_forward);
454 _rl_bind_if_unbound (_rl_term_kl, rl_backward);
473 bind_termcap_arrow_keys (emacs_standard_keymap);
455
474
456 _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
457 _rl_bind_if_unbound (_rl_term_kH, rl_end_of_line); /* End */
458
459#if defined (VI_MODE)
475#if defined (VI_MODE)
460 _rl_keymap = vi_movement_keymap;
476 bind_termcap_arrow_keys (vi_movement_keymap);
477 bind_termcap_arrow_keys (vi_insertion_keymap);
478#endif /* VI_MODE */
479
480 return 0;
481}
482
483/* Bind the arrow key sequences from the termcap description in MAP. */
484static void
485bind_termcap_arrow_keys (map)
486 Keymap map;
487{
488 Keymap xkeymap;
489
490 xkeymap = _rl_keymap;
491 _rl_keymap = map;
492
461 _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
462 _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
463 _rl_bind_if_unbound (_rl_term_kr, rl_forward);
464 _rl_bind_if_unbound (_rl_term_kl, rl_backward);
465
466 _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
493 _rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
494 _rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
495 _rl_bind_if_unbound (_rl_term_kr, rl_forward);
496 _rl_bind_if_unbound (_rl_term_kl, rl_backward);
497
498 _rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
467 _rl_bind_if_unbound (_rl_term_kH, rl_end_of_line); /* End */
468#endif /* VI_MODE */
499 _rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
469
470 _rl_keymap = xkeymap;
500
501 _rl_keymap = xkeymap;
471
472 return 0;
473}
474
475char *
476rl_get_termcap (cap)
477 const char *cap;
478{
479 register int i;
480
481 if (tcap_initialized == 0)
482 return ((char *)NULL);
483 for (i = 0; i < NUM_TC_STRINGS; i++)
484 {
485 if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
486 return *(tc_strings[i].tc_value);
487 }
488 return ((char *)NULL);
489}
490
491/* Re-initialize the terminal considering that the TERM/TERMCAP variable
492 has changed. */
493int
494rl_reset_terminal (terminal_name)
495 const char *terminal_name;
496{
497 _rl_init_terminal_io (terminal_name);
498 return 0;
499}
500
501/* A function for the use of tputs () */
502#ifdef _MINIX
503void
504_rl_output_character_function (c)
505 int c;
506{
507 putc (c, _rl_out_stream);
508}
509#else /* !_MINIX */
510int
511_rl_output_character_function (c)
512 int c;
513{
514 return putc (c, _rl_out_stream);
515}
516#endif /* !_MINIX */
517
518/* Write COUNT characters from STRING to the output stream. */
519void
520_rl_output_some_chars (string, count)
521 const char *string;
522 int count;
523{
524 fwrite (string, 1, count, _rl_out_stream);
525}
526
527/* Move the cursor back. */
528int
529_rl_backspace (count)
530 int count;
531{
532 register int i;
533
534 if (_rl_term_backspace)
535 for (i = 0; i < count; i++)
536 tputs (_rl_term_backspace, 1, _rl_output_character_function);
537 else
538 for (i = 0; i < count; i++)
539 putc ('\b', _rl_out_stream);
540 return 0;
541}
542
543/* Move to the start of the next line. */
544int
545rl_crlf ()
546{
547#if defined (NEW_TTY_DRIVER)
548 if (_rl_term_cr)
549 tputs (_rl_term_cr, 1, _rl_output_character_function);
550#endif /* NEW_TTY_DRIVER */
551 putc ('\n', _rl_out_stream);
552 return 0;
553}
554
555/* Ring the terminal bell. */
556int
557rl_ding ()
558{
559 if (readline_echoing_p)
560 {
561 switch (_rl_bell_preference)
562 {
563 case NO_BELL:
564 default:
565 break;
566 case VISIBLE_BELL:
567 if (_rl_visible_bell)
568 {
569 tputs (_rl_visible_bell, 1, _rl_output_character_function);
570 break;
571 }
572 /* FALLTHROUGH */
573 case AUDIBLE_BELL:
574 fprintf (stderr, "\007");
575 fflush (stderr);
576 break;
577 }
578 return (0);
579 }
580 return (-1);
581}
582
583/* **************************************************************** */
584/* */
585/* Controlling the Meta Key and Keypad */
586/* */
587/* **************************************************************** */
588
589void
590_rl_enable_meta_key ()
591{
592#if !defined (__DJGPP__)
593 if (term_has_meta && _rl_term_mm)
594 tputs (_rl_term_mm, 1, _rl_output_character_function);
595#endif
596}
597
598void
599_rl_control_keypad (on)
600 int on;
601{
602#if !defined (__DJGPP__)
603 if (on && _rl_term_ks)
604 tputs (_rl_term_ks, 1, _rl_output_character_function);
605 else if (!on && _rl_term_ke)
606 tputs (_rl_term_ke, 1, _rl_output_character_function);
607#endif
608}
502}
503
504char *
505rl_get_termcap (cap)
506 const char *cap;
507{
508 register int i;
509
510 if (tcap_initialized == 0)
511 return ((char *)NULL);
512 for (i = 0; i < NUM_TC_STRINGS; i++)
513 {
514 if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
515 return *(tc_strings[i].tc_value);
516 }
517 return ((char *)NULL);
518}
519
520/* Re-initialize the terminal considering that the TERM/TERMCAP variable
521 has changed. */
522int
523rl_reset_terminal (terminal_name)
524 const char *terminal_name;
525{
526 _rl_init_terminal_io (terminal_name);
527 return 0;
528}
529
530/* A function for the use of tputs () */
531#ifdef _MINIX
532void
533_rl_output_character_function (c)
534 int c;
535{
536 putc (c, _rl_out_stream);
537}
538#else /* !_MINIX */
539int
540_rl_output_character_function (c)
541 int c;
542{
543 return putc (c, _rl_out_stream);
544}
545#endif /* !_MINIX */
546
547/* Write COUNT characters from STRING to the output stream. */
548void
549_rl_output_some_chars (string, count)
550 const char *string;
551 int count;
552{
553 fwrite (string, 1, count, _rl_out_stream);
554}
555
556/* Move the cursor back. */
557int
558_rl_backspace (count)
559 int count;
560{
561 register int i;
562
563 if (_rl_term_backspace)
564 for (i = 0; i < count; i++)
565 tputs (_rl_term_backspace, 1, _rl_output_character_function);
566 else
567 for (i = 0; i < count; i++)
568 putc ('\b', _rl_out_stream);
569 return 0;
570}
571
572/* Move to the start of the next line. */
573int
574rl_crlf ()
575{
576#if defined (NEW_TTY_DRIVER)
577 if (_rl_term_cr)
578 tputs (_rl_term_cr, 1, _rl_output_character_function);
579#endif /* NEW_TTY_DRIVER */
580 putc ('\n', _rl_out_stream);
581 return 0;
582}
583
584/* Ring the terminal bell. */
585int
586rl_ding ()
587{
588 if (readline_echoing_p)
589 {
590 switch (_rl_bell_preference)
591 {
592 case NO_BELL:
593 default:
594 break;
595 case VISIBLE_BELL:
596 if (_rl_visible_bell)
597 {
598 tputs (_rl_visible_bell, 1, _rl_output_character_function);
599 break;
600 }
601 /* FALLTHROUGH */
602 case AUDIBLE_BELL:
603 fprintf (stderr, "\007");
604 fflush (stderr);
605 break;
606 }
607 return (0);
608 }
609 return (-1);
610}
611
612/* **************************************************************** */
613/* */
614/* Controlling the Meta Key and Keypad */
615/* */
616/* **************************************************************** */
617
618void
619_rl_enable_meta_key ()
620{
621#if !defined (__DJGPP__)
622 if (term_has_meta && _rl_term_mm)
623 tputs (_rl_term_mm, 1, _rl_output_character_function);
624#endif
625}
626
627void
628_rl_control_keypad (on)
629 int on;
630{
631#if !defined (__DJGPP__)
632 if (on && _rl_term_ks)
633 tputs (_rl_term_ks, 1, _rl_output_character_function);
634 else if (!on && _rl_term_ke)
635 tputs (_rl_term_ke, 1, _rl_output_character_function);
636#endif
637}
638
639/* **************************************************************** */
640/* */
641/* Controlling the Cursor */
642/* */
643/* **************************************************************** */
644
645/* Set the cursor appropriately depending on IM, which is one of the
646 insert modes (insert or overwrite). Insert mode gets the normal
647 cursor. Overwrite mode gets a very visible cursor. Only does
648 anything if we have both capabilities. */
649void
650_rl_set_cursor (im, force)
651 int im, force;
652{
653 if (_rl_term_ve && _rl_term_vs)
654 {
655 if (force || im != rl_insert_mode)
656 {
657 if (im == RL_IM_OVERWRITE)
658 tputs (_rl_term_vs, 1, _rl_output_character_function);
659 else
660 tputs (_rl_term_ve, 1, _rl_output_character_function);
661 }
662 }
663}