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 --- 62 unchanged lines hidden (view full) --- 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; |
143 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__) --- 23 unchanged lines hidden (view full) --- 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); 277 _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{ |
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 }, 299 { "kd", &_rl_term_kd }, 300 { "kh", &_rl_term_kh }, /* home */ 301 { "@7", &_rl_term_kH }, /* end */ 302 { "kl", &_rl_term_kl }, 303 { "kr", &_rl_term_kr }, 304 { "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 }, |
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) --- 8 unchanged lines hidden (view full) --- 332 tcap_initialized = 1; 333} 334 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; 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()) --- 14 unchanged lines hidden (view full) --- 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; 403 _rl_term_mm = _rl_term_mo = (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. */ 448 xkeymap = _rl_keymap; 449 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); |
455 |
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) 460 _rl_keymap = vi_movement_keymap; |
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 */ 467 _rl_bind_if_unbound (_rl_term_kH, rl_end_of_line); /* End */ |
468#endif /* VI_MODE */ 469 470 _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 --- 9 unchanged lines hidden (view full) --- 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 } --- 7 unchanged lines hidden (view full) --- 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} |