Skip to content

Instantly share code, notes, and snippets.

@wilbertcr
Created November 28, 2013 01:49
Show Gist options
  • Save wilbertcr/474c6a13e377dc8ce51a to your computer and use it in GitHub Desktop.
Save wilbertcr/474c6a13e377dc8ce51a to your computer and use it in GitHub Desktop.
int verase = 0;
int in_process(tp, buf, count, scode)
register tty_t *tp; /* terminal on which character has arrived */
char *buf; /* buffer with input characters */
int count; /* number of input characters */
int scode; /* scan code */
{
/* Characters have just been typed in. Process, save, and echo them. Return
* the number of characters processed.
*/
int ch, sig, ct;
int timeset = FALSE;
/* Send scancode if requested */
if (tp->tty_termios.c_iflag & SCANCODES) {
in_process_send_byte(tp, (scode & BYTE) | IN_EOT);
}
for (ct = 0; ct < count; ct++) {
/* Take one character. */
ch = *buf++ & BYTE;
/* Strip to seven bits? */
if (tp->tty_termios.c_iflag & ISTRIP)
ch &= 0x7F;
if (verase) {
int number = (int) ch;
for(;number>0;number--){
(void) back_over2(tp);
}
// if (!(tp->tty_termios.c_lflag & ECHOE)) {
// (void) tty_echo(tp, ch);
// }
verase = 0;
continue;
}
/* Input extensions? */
if (tp->tty_termios.c_lflag & IEXTEN) {
/* Previous character was a character escape? */
if (tp->tty_escaped) {
tp->tty_escaped = NOT_ESCAPED;
ch |= IN_ESC; /* protect character */
}
/* LNEXT (^V) to escape the next character? */
if (ch == tp->tty_termios.c_cc[VLNEXT]) {
tp->tty_escaped = ESCAPED;
rawecho(tp, '^');
rawecho(tp, '\b');
continue; /* do not store the escape */
}
/* REPRINT (^R) to reprint echoed characters? */
if (ch == tp->tty_termios.c_cc[VREPRINT]) {
reprint(tp);
continue;
}
}
/* _POSIX_VDISABLE is a normal character value, so better escape it. */
if (ch == _POSIX_VDISABLE)
ch |= IN_ESC;
/* Map CR to LF, ignore CR, or map LF to CR. */
if (ch == '\r') {
if (tp->tty_termios.c_iflag & IGNCR)
continue;
if (tp->tty_termios.c_iflag & ICRNL)
ch = '\n';
} else if (ch == '\n') {
if (tp->tty_termios.c_iflag & INLCR) ch = '\r';
}
/* Canonical mode? */
if (tp->tty_termios.c_lflag & ICANON) {
/* Erase processing (rub out of last character). */
if (ch == tp->tty_termios.c_cc[VERASE]) {
verase = 1;
continue;
}
/* Kill processing (remove current line). */
if (ch == tp->tty_termios.c_cc[VKILL]) {
while (back_over(tp)) {}
if (!(tp->tty_termios.c_lflag & ECHOE)) {
(void) tty_echo(tp, ch);
if (tp->tty_termios.c_lflag & ECHOK)
rawecho(tp, '\n');
}
continue;
}
/* EOF (^D) means end-of-file, an invisible "line break". */
if (ch == tp->tty_termios.c_cc[VEOF]) ch |= IN_EOT | IN_EOF;
/* The line may be returned to the user after an LF. */
if (ch == '\n') ch |= IN_EOT;
/* Same thing with EOL, whatever it may be. */
if (ch == tp->tty_termios.c_cc[VEOL]) ch |= IN_EOT;
}
/* Start/stop input control? */
if (tp->tty_termios.c_iflag & IXON) {
/* Output stops on STOP (^S). */
if (ch == tp->tty_termios.c_cc[VSTOP]) {
tp->tty_inhibited = STOPPED;
tp->tty_events = 1;
continue;
}
/* Output restarts on START (^Q) or any character if IXANY. */
if (tp->tty_inhibited) {
if (ch == tp->tty_termios.c_cc[VSTART]
|| (tp->tty_termios.c_iflag & IXANY)) {
tp->tty_inhibited = RUNNING;
tp->tty_events = 1;
if (ch == tp->tty_termios.c_cc[VSTART])
continue;
}
}
}
if (tp->tty_termios.c_lflag & ISIG) {
/* Check for INTR (^?) and QUIT (^\) characters. */
if (ch == tp->tty_termios.c_cc[VINTR]
|| ch == tp->tty_termios.c_cc[VQUIT]) {
sig = SIGINT;
if (ch == tp->tty_termios.c_cc[VQUIT]) sig = SIGQUIT;
sigchar(tp, sig, 1);
(void) tty_echo(tp, ch);
continue;
}
}
/* Is there space in the input buffer? */
if (tp->tty_incount == buflen(tp->tty_inbuf)) {
/* No space; discard in canonical mode, keep in raw mode. */
if (tp->tty_termios.c_lflag & ICANON) continue;
break;
}
if (!(tp->tty_termios.c_lflag & ICANON)) {
/* In raw mode all characters are "line breaks". */
ch |= IN_EOT;
/* Start an inter-byte timer? */
if (!timeset && tp->tty_termios.c_cc[VMIN] > 0
&& tp->tty_termios.c_cc[VTIME] > 0) {
settimer(tp, TRUE);
timeset = TRUE;
}
}
/* Perform the intricate function of echoing. */
if (tp->tty_termios.c_lflag & (ECHO|ECHONL)) ch = tty_echo(tp, ch);
/* Send processed byte of input unless scancodes sent instead */
if (!(tp->tty_termios.c_iflag & SCANCODES)) {
in_process_send_byte(tp, ch);
}
}
return ct;
}
static int back_over2(tp)
register tty_t *tp;
{
/* Backspace to previous character on screen and erase it. */
u16_t *head;
int len;
if (tp->tty_incount == 0)
return(0); /* queue empty */
head = tp->tty_inhead;
if (head == tp->tty_inbuf)
head = bufend(tp->tty_inbuf);
if (*--head & IN_EOT)
return(0); /* can't erase "line breaks" */
if (tp->tty_reprint)
reprint(tp); /* reprint if messed up */
tp->tty_inhead = head;
// tp->tty_incount--;
if (tp->tty_termios.c_lflag & ECHOE) {
len = (*head & IN_LEN) >> IN_LSHIFT;
while (len > 0) {
rawecho(tp, '\b');
// rawecho(tp, ' ');
// rawecho(tp, '\b');
len--;
}
}
return(1); /* one character erased */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment