-
-
Save wilbertcr/474c6a13e377dc8ce51a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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