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