| 747 | } |
| 748 | |
| 749 | static int |
| 750 | ttydisc_rubchar(struct tty *tp) |
| 751 | { |
| 752 | char c; |
| 753 | int quote; |
| 754 | unsigned int prevpos, tablen; |
| 755 | |
| 756 | if (ttyinq_peekchar(&tp->t_inq, &c, "e) != 0) |
| 757 | return (-1); |
| 758 | ttyinq_unputchar(&tp->t_inq); |
| 759 | |
| 760 | if (CMP_FLAG(l, ECHO)) { |
| 761 | /* |
| 762 | * Remove the character from the screen. This is even |
| 763 | * safe for characters that span multiple characters |
| 764 | * (tabs, quoted, etc). |
| 765 | */ |
| 766 | if (tp->t_writepos >= tp->t_column) { |
| 767 | /* Retype the sentence. */ |
| 768 | ttydisc_reprint(tp); |
| 769 | } else if (CMP_FLAG(l, ECHOE)) { |
| 770 | if (CTL_PRINT(c, quote)) { |
| 771 | /* Remove ^X formatted chars. */ |
| 772 | if (CMP_FLAG(l, ECHOCTL)) { |
| 773 | tp->t_column -= 2; |
| 774 | ttyoutq_write_nofrag(&tp->t_outq, |
| 775 | "\b\b \b\b", 6); |
| 776 | } |
| 777 | } else if (c == ' ') { |
| 778 | /* Space character needs no rubbing. */ |
| 779 | tp->t_column -= 1; |
| 780 | ttyoutq_write_nofrag(&tp->t_outq, "\b", 1); |
| 781 | } else if (c == CTAB) { |
| 782 | /* |
| 783 | * Making backspace work with tabs is |
| 784 | * quite hard. Recalculate the length of |
| 785 | * this character and remove it. |
| 786 | * |
| 787 | * Because terminal settings could be |
| 788 | * changed while the line is being |
| 789 | * inserted, the calculations don't have |
| 790 | * to be correct. Make sure we keep the |
| 791 | * tab length within proper bounds. |
| 792 | */ |
| 793 | prevpos = ttydisc_recalc_linelength(tp); |
| 794 | if (prevpos >= tp->t_column) |
| 795 | tablen = 1; |
| 796 | else |
| 797 | tablen = tp->t_column - prevpos; |
| 798 | if (tablen > 8) |
| 799 | tablen = 8; |
| 800 | |
| 801 | tp->t_column = prevpos; |
| 802 | ttyoutq_write_nofrag(&tp->t_outq, |
| 803 | "\b\b\b\b\b\b\b\b", tablen); |
| 804 | return (0); |
| 805 | } else { |
| 806 | /* |
no test coverage detected