[ dejagnu/ChangeLog ]
[deliverable/binutils-gdb.git] / readline / terminal.c
CommitLineData
d60d9f65
SS
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
1b17e766 10 as published by the Free Software Foundation; either version 2, or
d60d9f65
SS
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,
1b17e766 21 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
d60d9f65
SS
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
d60d9f65 49#include <stdio.h>
d60d9f65
SS
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
30083a32
EZ
58#ifdef __MSDOS__
59# include <pc.h>
60#endif
61
d60d9f65
SS
62#include "rltty.h"
63#include "tcap.h"
64
65/* Some standard library routines. */
66#include "readline.h"
67#include "history.h"
68
1b17e766
EZ
69#include "rlprivate.h"
70#include "rlshell.h"
8f2eba6e 71
d60d9f65
SS
72/* **************************************************************** */
73/* */
74/* Terminal and Termcap */
75/* */
76/* **************************************************************** */
77
30083a32 78#ifndef __MSDOS__
d60d9f65
SS
79static char *term_buffer = (char *)NULL;
80static char *term_string_buffer = (char *)NULL;
81
d60d9f65
SS
82/* Non-zero means this terminal can't really do anything. */
83static int dumb_term;
30083a32
EZ
84#endif /* !__MSDOS__ */
85
86static int tcap_initialized;
d60d9f65
SS
87
88#if !defined (__linux__)
89# if defined (__EMX__) || defined (NEED_EXTERN_PC)
90extern
91# endif /* __EMX__ || NEED_EXTERN_PC */
92char PC, *BC, *UP;
93#endif /* __linux__ */
94
95/* Some strings to control terminal actions. These are output by tputs (). */
96char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
97char *term_pc;
98
99/* Non-zero if we determine that the terminal can do character insertion. */
100int terminal_can_insert = 0;
101
102/* How to insert characters. */
103char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
104
105/* How to delete characters. */
106char *term_dc, *term_DC;
107
108#if defined (HACK_TERMCAP_MOTION)
109char *term_forward_char;
110#endif /* HACK_TERMCAP_MOTION */
111
112/* How to go up a line. */
113char *term_up;
114
115/* A visible bell, if the terminal can be made to flash the screen. */
116static char *visible_bell;
117
118/* Non-zero means the terminal can auto-wrap lines. */
119int _rl_term_autowrap;
120
121/* Non-zero means that this terminal has a meta key. */
122static int term_has_meta;
123
124/* The sequences to write to turn on and off the meta key, if this
125 terminal has one. */
126static char *term_mm, *term_mo;
127
128/* The key sequences output by the arrow keys, if this terminal has any. */
129static char *term_ku, *term_kd, *term_kr, *term_kl;
130
131/* How to initialize and reset the arrow keys, if this terminal has any. */
132static char *term_ks, *term_ke;
133
134/* The key sequences sent by the Home and End keys, if any. */
135static char *term_kh, *term_kH;
136
137/* Variables that hold the screen dimensions, used by the display code. */
138int screenwidth, screenheight, screenchars;
139
140/* Non-zero means the user wants to enable the keypad. */
141int _rl_enable_keypad;
142
143/* Non-zero means the user wants to enable a meta key. */
144int _rl_enable_meta = 1;
145
1b17e766
EZ
146#if defined (__EMX__)
147static void
148_emx_get_screensize (swp, shp)
149 int *swp, *shp;
150{
151 int sz[2];
152
153 _scrsize (sz);
154
155 if (swp)
156 *swp = sz[0];
157 if (shp)
158 *shp = sz[1];
159}
160#endif
161
d60d9f65
SS
162/* Get readline's idea of the screen size. TTY is a file descriptor open
163 to the terminal. If IGNORE_ENV is true, we do not pay attention to the
164 values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
165 non-null serve to check whether or not we have initialized termcap. */
166void
167_rl_get_screen_size (tty, ignore_env)
168 int tty, ignore_env;
169{
170 char *ss;
171#if defined (TIOCGWINSZ)
172 struct winsize window_size;
173#endif /* TIOCGWINSZ */
d60d9f65
SS
174
175#if defined (TIOCGWINSZ)
176 if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
177 {
178 screenwidth = (int) window_size.ws_col;
179 screenheight = (int) window_size.ws_row;
180 }
181#endif /* TIOCGWINSZ */
182
183#if defined (__EMX__)
1b17e766 184 _emx_get_screensize (&screenwidth, &screenheight);
d60d9f65
SS
185#endif
186
187 /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
188 is unset. */
189 if (screenwidth <= 0)
190 {
191 if (ignore_env == 0 && (ss = get_env_value ("COLUMNS")))
192 screenwidth = atoi (ss);
193
30083a32
EZ
194#if defined (__DJGPP__)
195 if (screenwidth <= 0)
196 screenwidth = ScreenCols ();
197#else
d60d9f65
SS
198 if (screenwidth <= 0 && term_string_buffer)
199 screenwidth = tgetnum ("co");
771578d1 200#endif
d60d9f65
SS
201 }
202
203 /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
204 is unset. */
205 if (screenheight <= 0)
206 {
207 if (ignore_env == 0 && (ss = get_env_value ("LINES")))
208 screenheight = atoi (ss);
209
30083a32
EZ
210#if defined (__DJGPP__)
211 if (screenheight <= 0)
212 screenheight = ScreenRows ();
213#else
d60d9f65
SS
214 if (screenheight <= 0 && term_string_buffer)
215 screenheight = tgetnum ("li");
771578d1 216#endif
d60d9f65
SS
217 }
218
219 /* If all else fails, default to 80x24 terminal. */
220 if (screenwidth <= 1)
221 screenwidth = 80;
222
223 if (screenheight <= 0)
224 screenheight = 24;
225
226 /* If we're being compiled as part of bash, set the environment
227 variables $LINES and $COLUMNS to new values. Otherwise, just
228 do a pair of putenv () or setenv () calls. */
229 set_lines_and_columns (screenheight, screenwidth);
230
1b17e766 231 if (_rl_term_autowrap == 0)
d60d9f65
SS
232 screenwidth--;
233
234 screenchars = screenwidth * screenheight;
235}
236
237void
238_rl_set_screen_size (rows, cols)
239 int rows, cols;
240{
241 screenheight = rows;
242 screenwidth = cols;
243
244 if (_rl_term_autowrap == 0)
245 screenwidth--;
246
247 screenchars = screenwidth * screenheight;
248}
249
c862e87b
JM
250void
251rl_resize_terminal ()
252{
253 if (readline_echoing_p)
254 {
255 _rl_get_screen_size (fileno (rl_instream), 1);
256 _rl_redisplay_after_sigwinch ();
257 }
258}
259
d60d9f65
SS
260struct _tc_string {
261 char *tc_var;
262 char **tc_value;
263};
264
265/* This should be kept sorted, just in case we decide to change the
266 search algorithm to something smarter. */
267static struct _tc_string tc_strings[] =
268{
1b17e766
EZ
269 { "DC", &term_DC },
270 { "IC", &term_IC },
271 { "ce", &term_clreol },
272 { "cl", &term_clrpag },
273 { "cr", &term_cr },
274 { "dc", &term_dc },
275 { "ei", &term_ei },
276 { "ic", &term_ic },
277 { "im", &term_im },
278 { "kd", &term_kd },
279 { "kh", &term_kh }, /* home */
280 { "kH", &term_kH }, /* end */
281 { "kl", &term_kl },
282 { "kr", &term_kr },
283 { "ku", &term_ku },
284 { "ks", &term_ks },
285 { "ke", &term_ke },
286 { "le", &term_backspace },
287 { "mm", &term_mm },
288 { "mo", &term_mo },
d60d9f65 289#if defined (HACK_TERMCAP_MOTION)
1b17e766 290 { "nd", &term_forward_char },
d60d9f65 291#endif
1b17e766
EZ
292 { "pc", &term_pc },
293 { "up", &term_up },
294 { "vb", &visible_bell },
d60d9f65
SS
295};
296
297#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
298
299/* Read the desired terminal capability strings into BP. The capabilities
300 are described in the TC_STRINGS table. */
301static void
302get_term_capabilities (bp)
303 char **bp;
304{
1b17e766 305#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
d60d9f65
SS
306 register int i;
307
308 for (i = 0; i < NUM_TC_STRINGS; i++)
309 *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
771578d1 310#endif
d60d9f65
SS
311 tcap_initialized = 1;
312}
313
1b17e766
EZ
314#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
315#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
316
d60d9f65
SS
317int
318_rl_init_terminal_io (terminal_name)
319 char *terminal_name;
320{
d60d9f65 321 char *term, *buffer;
1b17e766 322 int tty, tgetent_ret;
d60d9f65
SS
323 Keymap xkeymap;
324
325 term = terminal_name ? terminal_name : get_env_value ("TERM");
1b17e766
EZ
326 term_clrpag = term_cr = term_clreol = (char *)NULL;
327 tty = rl_instream ? fileno (rl_instream) : 0;
328 screenwidth = screenheight = 0;
d60d9f65 329
1b17e766
EZ
330 if (term == 0)
331 term = "dumb";
d60d9f65 332
30083a32
EZ
333#ifdef __MSDOS__
334 term_im = term_ei = term_ic = term_IC = (char *)NULL;
335 term_up = term_dc = term_DC = visible_bell = (char *)NULL;
336 term_ku = term_kd = term_kl = term_kr = (char *)NULL;
337 term_mm = term_mo = (char *)NULL;
338 terminal_can_insert = term_has_meta = _rl_term_autowrap = 0;
339 term_cr = "\r";
340
341 _rl_get_screen_size (tty, 0);
342#else /* !__MSDOS__ */
1b17e766
EZ
343 /* I've separated this out for later work on not calling tgetent at all
344 if the calling application has supplied a custom redisplay function,
345 (and possibly if the application has supplied a custom input function). */
346 if (CUSTOM_REDISPLAY_FUNC())
347 {
348 tgetent_ret = -1;
349 }
350 else
351 {
352 if (term_string_buffer == 0)
353 term_string_buffer = xmalloc(2032);
d60d9f65 354
1b17e766
EZ
355 if (term_buffer == 0)
356 term_buffer = xmalloc(4080);
d60d9f65 357
1b17e766 358 buffer = term_string_buffer;
d60d9f65 359
1b17e766
EZ
360 tgetent_ret = tgetent (term_buffer, term);
361 }
d60d9f65 362
1b17e766 363 if (tgetent_ret <= 0)
d60d9f65 364 {
1b17e766
EZ
365 FREE (term_string_buffer);
366 FREE (term_buffer);
367 buffer = term_buffer = term_string_buffer = (char *)NULL;
368
d60d9f65 369 dumb_term = 1;
1b17e766
EZ
370 _rl_term_autowrap = 0; /* used by _rl_get_screen_size */
371
372#if defined (__EMX__)
373 _emx_get_screensize (&screenwidth, &screenheight);
374 screenwidth--;
375#else /* !__EMX__ */
376 _rl_get_screen_size (tty, 0);
377#endif /* !__EMX__ */
378
379 /* Defaults. */
380 if (screenwidth <= 0 || screenheight <= 0)
381 {
382 screenwidth = 79;
383 screenheight = 24;
384 }
385
386 /* Everything below here is used by the redisplay code (tputs). */
387 screenchars = screenwidth * screenheight;
d60d9f65
SS
388 term_cr = "\r";
389 term_im = term_ei = term_ic = term_IC = (char *)NULL;
390 term_up = term_dc = term_DC = visible_bell = (char *)NULL;
391 term_ku = term_kd = term_kl = term_kr = (char *)NULL;
1b17e766 392 term_mm = term_mo = (char *)NULL;
d60d9f65
SS
393#if defined (HACK_TERMCAP_MOTION)
394 term_forward_char = (char *)NULL;
395#endif
1b17e766
EZ
396 terminal_can_insert = term_has_meta = 0;
397
398 /* Reasonable defaults for tgoto(). Readline currently only uses
399 tgoto if term_IC or term_DC is defined, but just in case we
400 change that later... */
401 PC = '\0';
402 BC = term_backspace = "\b";
403 UP = term_up;
404
d60d9f65
SS
405 return 0;
406 }
407
408 get_term_capabilities (&buffer);
409
410 /* Set up the variables that the termcap library expects the application
411 to provide. */
412 PC = term_pc ? *term_pc : 0;
413 BC = term_backspace;
414 UP = term_up;
415
416 if (!term_cr)
417 term_cr = "\r";
418
d60d9f65
SS
419 _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
420
421 _rl_get_screen_size (tty, 0);
422
423 /* "An application program can assume that the terminal can do
424 character insertion if *any one of* the capabilities `IC',
425 `im', `ic' or `ip' is provided." But we can't do anything if
426 only `ip' is provided, so... */
427 terminal_can_insert = (term_IC || term_im || term_ic);
428
429 /* Check to see if this terminal has a meta key and clear the capability
430 variables if there is none. */
431 term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
432 if (!term_has_meta)
433 term_mm = term_mo = (char *)NULL;
434
30083a32
EZ
435#endif /* !__MSDOS__ */
436
d60d9f65
SS
437 /* Attempt to find and bind the arrow keys. Do not override already
438 bound keys in an overzealous attempt, however. */
439 xkeymap = _rl_keymap;
440
441 _rl_keymap = emacs_standard_keymap;
442 _rl_bind_if_unbound (term_ku, rl_get_previous_history);
443 _rl_bind_if_unbound (term_kd, rl_get_next_history);
444 _rl_bind_if_unbound (term_kr, rl_forward);
445 _rl_bind_if_unbound (term_kl, rl_backward);
446
447 _rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
448 _rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
449
450#if defined (VI_MODE)
451 _rl_keymap = vi_movement_keymap;
452 _rl_bind_if_unbound (term_ku, rl_get_previous_history);
453 _rl_bind_if_unbound (term_kd, rl_get_next_history);
454 _rl_bind_if_unbound (term_kr, rl_forward);
455 _rl_bind_if_unbound (term_kl, rl_backward);
456
457 _rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
458 _rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
459#endif /* VI_MODE */
460
461 _rl_keymap = xkeymap;
462
d60d9f65
SS
463 return 0;
464}
465
466char *
467rl_get_termcap (cap)
468 char *cap;
469{
470 register int i;
471
472 if (tcap_initialized == 0)
473 return ((char *)NULL);
474 for (i = 0; i < NUM_TC_STRINGS; i++)
475 {
476 if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
477 return *(tc_strings[i].tc_value);
478 }
479 return ((char *)NULL);
480}
481
482/* Re-initialize the terminal considering that the TERM/TERMCAP variable
483 has changed. */
484int
485rl_reset_terminal (terminal_name)
486 char *terminal_name;
487{
488 _rl_init_terminal_io (terminal_name);
489 return 0;
490}
491
492/* A function for the use of tputs () */
493#ifdef _MINIX
494void
495_rl_output_character_function (c)
496 int c;
497{
498 putc (c, _rl_out_stream);
499}
500#else /* !_MINIX */
501int
502_rl_output_character_function (c)
503 int c;
504{
505 return putc (c, _rl_out_stream);
506}
507#endif /* !_MINIX */
1b17e766 508
d60d9f65
SS
509/* Write COUNT characters from STRING to the output stream. */
510void
511_rl_output_some_chars (string, count)
512 char *string;
513 int count;
514{
515 fwrite (string, 1, count, _rl_out_stream);
516}
517
518/* Move the cursor back. */
519int
520_rl_backspace (count)
521 int count;
522{
523 register int i;
524
30083a32 525#ifndef __MSDOS__
d60d9f65
SS
526 if (term_backspace)
527 for (i = 0; i < count; i++)
528 tputs (term_backspace, 1, _rl_output_character_function);
529 else
30083a32 530#endif
d60d9f65
SS
531 for (i = 0; i < count; i++)
532 putc ('\b', _rl_out_stream);
533 return 0;
534}
535
536/* Move to the start of the next line. */
537int
538crlf ()
539{
540#if defined (NEW_TTY_DRIVER)
541 if (term_cr)
542 tputs (term_cr, 1, _rl_output_character_function);
543#endif /* NEW_TTY_DRIVER */
544 putc ('\n', _rl_out_stream);
545 return 0;
546}
547
548/* Ring the terminal bell. */
549int
550ding ()
551{
552 if (readline_echoing_p)
553 {
d60d9f65
SS
554 switch (_rl_bell_preference)
555 {
556 case NO_BELL:
557 default:
558 break;
559 case VISIBLE_BELL:
30083a32
EZ
560#ifdef __MSDOS__
561 ScreenVisualBell ();
562 break;
563#else
d60d9f65
SS
564 if (visible_bell)
565 {
566 tputs (visible_bell, 1, _rl_output_character_function);
567 break;
568 }
30083a32 569#endif
d60d9f65
SS
570 /* FALLTHROUGH */
571 case AUDIBLE_BELL:
572 fprintf (stderr, "\007");
573 fflush (stderr);
574 break;
575 }
d60d9f65
SS
576 return (0);
577 }
578 return (-1);
579}
580
581/* **************************************************************** */
582/* */
583/* Controlling the Meta Key and Keypad */
584/* */
585/* **************************************************************** */
586
587void
588_rl_enable_meta_key ()
589{
1b17e766 590#if !defined (__DJGPP__)
d60d9f65
SS
591 if (term_has_meta && term_mm)
592 tputs (term_mm, 1, _rl_output_character_function);
771578d1 593#endif
d60d9f65
SS
594}
595
596void
597_rl_control_keypad (on)
598 int on;
599{
1b17e766 600#if !defined (__DJGPP__)
d60d9f65
SS
601 if (on && term_ks)
602 tputs (term_ks, 1, _rl_output_character_function);
603 else if (!on && term_ke)
604 tputs (term_ke, 1, _rl_output_character_function);
771578d1 605#endif
d60d9f65 606}
This page took 0.144555 seconds and 4 git commands to generate.