Browse Source

tty: ascii DELETE for backspace; no serial conversion

K. Lange 3 years ago
parent
commit
092ca7c196
5 changed files with 36 additions and 27 deletions
  1. 8 2
      apps/stty.c
  2. 6 0
      apps/terminal-vga.c
  3. 6 0
      apps/terminal.c
  4. 14 10
      kernel/fs/tty.c
  5. 2 15
      modules/serial.c

+ 8 - 2
apps/stty.c

@@ -21,6 +21,8 @@ static void print_cc(struct termios * t, const char * lbl, int val, int def) {
 		fprintf(stdout, "%s = <undef>; ", lbl);
 	} else if (c < 32) {
 		fprintf(stdout, "%s = ^%c; ", lbl, '@' + c);
+	} else if (c == 0x7F) {
+		fprintf(stdout, "%s = ^?; ", lbl);
 	} else {
 		fprintf(stdout, "%s = %c; ", lbl, c);
 	}
@@ -52,7 +54,11 @@ static void set_char_(struct termios *t, const char * lbl, int val, const char *
 			t->c_cc[val] = *arg;
 		} else if (*arg == '^') { /* ^c, etc. */
 			int v = toupper(arg[1]);
-			t->c_cc[val] = v - '@';
+			if (v == '?') { /* special case */
+				t->c_cc[val] = 0x7F;
+			} else {
+				t->c_cc[val] = v - '@';
+			}
 		} else {
 			/* Assume decimal for now */
 			int v = atoi(arg);
@@ -233,7 +239,7 @@ int main(int argc, char * argv[]) {
 			t.c_cflag = CREAD | CS8;
 			t.c_cc[VEOF]   =  4; /* ^D */
 			t.c_cc[VEOL]   =  0; /* Not set */
-			t.c_cc[VERASE] = '\b';
+			t.c_cc[VERASE] = 0x7F; /* ^? */
 			t.c_cc[VINTR]  =  3; /* ^C */
 			t.c_cc[VKILL]  = 21; /* ^U */
 			t.c_cc[VMIN]   =  1;

+ 6 - 0
apps/terminal-vga.c

@@ -888,6 +888,12 @@ void key_event(int ret, key_event_t * event) {
 			return;
 		}
 
+		/* BACKSPACE = reads as ^H, should be ^? */
+		if (event->keycode == 8) {
+			handle_input(0x7F);
+			return;
+		}
+
 		handle_input(event->key);
 	} else {
 		if (event->action == KEY_ACTION_UP) return;

+ 6 - 0
apps/terminal.c

@@ -1660,6 +1660,12 @@ static void key_event(int ret, key_event_t * event) {
 			return;
 		}
 
+		/* BACKSPACE = reads as ^H, should be ^? */
+		if (event->keycode == 8) {
+			handle_input(0x7F);
+			return;
+		}
+
 		/* Pass key value to PTY */
 		handle_input(event->key);
 	} else {

+ 14 - 10
kernel/fs/tty.c

@@ -78,12 +78,16 @@ void tty_output_process(pty_t * pty, uint8_t c) {
 	output_process_slave(pty, c);
 }
 
+static int is_control(int c) {
+	return c < ' ' || c == 0x7F;
+}
+
 static void erase_one(pty_t * pty, int erase) {
 	if (pty->canon_buflen > 0) {
 		/* How many do we backspace? */
 		int vwidth = 1;
 		pty->canon_buflen--;
-		if (pty->canon_buffer[pty->canon_buflen] < ' ') {
+		if (is_control(pty->canon_buffer[pty->canon_buflen])) {
 			/* Erase ^@ */
 			vwidth = 2;
 		}
@@ -108,9 +112,9 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 			pty->canon_buflen++;
 		}
 		if (pty->tios.c_lflag & ECHO) {
-			if (c < ' ') {
+			if (is_control(c)) {
 				output_process(pty, '^');
-				output_process(pty, '@'+c);
+				output_process(pty, ('@'+c) % 128);
 			} else {
 				output_process(pty, c);
 			}
@@ -121,7 +125,7 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 		if (c == pty->tios.c_cc[VINTR]) {
 			if (pty->tios.c_lflag & ECHO) {
 				output_process(pty, '^');
-				output_process(pty, '@' + c);
+				output_process(pty, ('@' + c) % 128);
 				output_process(pty, '\n');
 			}
 			clear_input_buffer(pty);
@@ -133,7 +137,7 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 		if (c == pty->tios.c_cc[VQUIT]) {
 			if (pty->tios.c_lflag & ECHO) {
 				output_process(pty, '^');
-				output_process(pty, '@' + c);
+				output_process(pty, ('@' + c) % 128);
 				output_process(pty, '\n');
 			}
 			clear_input_buffer(pty);
@@ -183,7 +187,7 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 			}
 			if ((pty->tios.c_lflag & ECHO) && ! (pty->tios.c_lflag & ECHOK)) {
 				output_process(pty, '^');
-				output_process(pty, '@' + c);
+				output_process(pty, ('@' + c) % 128);
 			}
 			return;
 		}
@@ -192,7 +196,7 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 			erase_one(pty, pty->tios.c_lflag & ECHOE);
 			if ((pty->tios.c_lflag & ECHO) && ! (pty->tios.c_lflag & ECHOE)) {
 				output_process(pty, '^');
-				output_process(pty, '@' + c);
+				output_process(pty, ('@' + c) % 128);
 			}
 			return;
 		}
@@ -210,9 +214,9 @@ void tty_input_process(pty_t * pty, uint8_t c) {
 			pty->canon_buflen++;
 		}
 		if (pty->tios.c_lflag & ECHO) {
-			if (c < ' ' && c != '\n') {
+			if (is_control(c) && c != '\n') {
 				output_process(pty, '^');
-				output_process(pty, '@'+c);
+				output_process(pty, ('@' + c) % 128);
 			} else {
 				output_process(pty, c);
 			}
@@ -666,7 +670,7 @@ pty_t * pty_new(struct winsize * size) {
 	pty->tios.c_cflag = CREAD | CS8;
 	pty->tios.c_cc[VEOF]   =  4; /* ^D */
 	pty->tios.c_cc[VEOL]   =  0; /* Not set */
-	pty->tios.c_cc[VERASE] = '\b';
+	pty->tios.c_cc[VERASE] = 0x7f; /* ^? */
 	pty->tios.c_cc[VINTR]  =  3; /* ^C */
 	pty->tios.c_cc[VKILL]  = 21; /* ^U */
 	pty->tios.c_cc[VMIN]   =  1;

+ 2 - 15
modules/serial.c

@@ -29,17 +29,6 @@ static fs_node_t * _serial_port_b = NULL;
 static fs_node_t * _serial_port_c = NULL;
 static fs_node_t * _serial_port_d = NULL;
 
-static uint8_t convert(uint8_t in) {
-	switch (in) {
-		case 0x7F:
-			return 0x08;
-		case 0x0D:
-			return '\n';
-		default:
-			return in;
-	}
-}
-
 static fs_node_t ** pipe_for_port(int port) {
 	switch (port) {
 		case SERIAL_PORT_A: return &_serial_port_a;
@@ -60,8 +49,7 @@ static int serial_handler_ac(struct regs *r) {
 	}
 	serial = serial_recv(port);
 	irq_ack(SERIAL_IRQ_AC);
-	uint8_t buf[] = {convert(serial), 0};
-	write_fs(*pipe_for_port(port), 0, 1, buf);
+	write_fs(*pipe_for_port(port), 0, 1, (uint8_t*)&serial);
 	return 1;
 }
 
@@ -76,8 +64,7 @@ static int serial_handler_bd(struct regs *r) {
 	}
 	serial = serial_recv(port);
 	irq_ack(SERIAL_IRQ_BD);
-	uint8_t buf[] = {convert(serial), 0};
-	write_fs(*pipe_for_port(port), 0, 1, buf);
+	write_fs(*pipe_for_port(port), 0, 1, (uint8_t*)&serial);
 	return 1;
 }