Fix ICANON (lflag) and add more key handling to PS/2
This commit is contained in:
+14
-13
@@ -76,6 +76,15 @@ static const char ps2_key_table_1[128] = {
|
||||
[0x7F] = 0
|
||||
};
|
||||
|
||||
static const char ps2_e0_trans[128] = {
|
||||
[0x47] = INPUT_KEY_HOME,
|
||||
[0x48] = INPUT_KEY_UP,
|
||||
[0x4B] = INPUT_KEY_LEFT,
|
||||
[0x4D] = INPUT_KEY_RIGHT,
|
||||
[0x4F] = INPUT_KEY_END,
|
||||
[0x50] = INPUT_KEY_DOWN,
|
||||
};
|
||||
|
||||
uint32_t ps2_irq_keyboard(void *ctx) {
|
||||
uint8_t st = inb(0x64);
|
||||
|
||||
@@ -88,19 +97,11 @@ uint32_t ps2_irq_keyboard(void *ctx) {
|
||||
if (key == 0xE0) {
|
||||
key = inb(0x60);
|
||||
|
||||
switch (key) {
|
||||
case 0x48:
|
||||
input_scan(INPUT_KEY_UP);
|
||||
break;
|
||||
case 0x50:
|
||||
input_scan(INPUT_KEY_DOWN);
|
||||
break;
|
||||
case 0x4B:
|
||||
input_scan(INPUT_KEY_LEFT);
|
||||
break;
|
||||
case 0x4D:
|
||||
input_scan(INPUT_KEY_RIGHT);
|
||||
break;
|
||||
if (key < 128) {
|
||||
key = ps2_e0_trans[key];
|
||||
if (key) {
|
||||
input_scan(key);
|
||||
}
|
||||
}
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
||||
@@ -31,13 +31,11 @@ void input_scan(uint8_t c) {
|
||||
case INPUT_KEY_HOME:
|
||||
console_type(g_keyboard_console, '\033');
|
||||
console_type(g_keyboard_console, '[');
|
||||
console_type(g_keyboard_console, '[');
|
||||
console_type(g_keyboard_console, 'H');
|
||||
break;
|
||||
case INPUT_KEY_END:
|
||||
console_type(g_keyboard_console, '\033');
|
||||
console_type(g_keyboard_console, '[');
|
||||
console_type(g_keyboard_console, '[');
|
||||
console_type(g_keyboard_console, 'F');
|
||||
break;
|
||||
default:
|
||||
|
||||
+2
-11
@@ -24,11 +24,6 @@ ssize_t line_read(struct chrdev *chr, void *buf, size_t pos, size_t lim) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(chr->tc.c_iflag & ICANON)) {
|
||||
// Just spit out data as soon as it's available
|
||||
return simple_line_read(chr, buf, pos, lim);
|
||||
}
|
||||
|
||||
// NO ICANON YET
|
||||
// TODO: pass this through for non-canonical mode
|
||||
while (rem) {
|
||||
@@ -47,7 +42,7 @@ ssize_t line_read(struct chrdev *chr, void *buf, size_t pos, size_t lim) {
|
||||
}
|
||||
}
|
||||
|
||||
if (c == 0x17 && chr->tc.c_iflag & ICANON) {
|
||||
if (c == 0x17 && chr->tc.c_lflag & ICANON) {
|
||||
// Erase until the beginning of the word
|
||||
// TODO: erase preceding space groups
|
||||
while (rd) {
|
||||
@@ -65,7 +60,7 @@ ssize_t line_read(struct chrdev *chr, void *buf, size_t pos, size_t lim) {
|
||||
|
||||
continue;
|
||||
}
|
||||
if (c == 0x7F && chr->tc.c_iflag & ICANON) {
|
||||
if (c == 0x7F && chr->tc.c_lflag & ICANON) {
|
||||
if (rd) {
|
||||
if (chr->tc.c_lflag & ECHOE) {
|
||||
tty_puts(chr, "\033[D \033[D");
|
||||
@@ -119,9 +114,5 @@ ssize_t simple_line_read(struct chrdev *chr, void *buf, size_t pos, size_t lim)
|
||||
++rd;
|
||||
}
|
||||
|
||||
if (rd == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rd;
|
||||
}
|
||||
|
||||
+1
-1
@@ -73,7 +73,7 @@ void tty_data_write(struct chrdev *tty, char c) {
|
||||
ring_signal(&tty->buffer, 0);
|
||||
break;
|
||||
case '\033':
|
||||
if ((tty->tc.c_lflag & ECHO) || (tty->tc.c_iflag & ICANON)) {
|
||||
if ((tty->tc.c_lflag & ECHO) && (tty->tc.c_iflag & ICANON)) {
|
||||
tty_puts(tty, "^[");
|
||||
}
|
||||
break;
|
||||
|
||||
+1
-1
@@ -413,7 +413,7 @@ static int sys_select_get_ready(struct ofile *fd) {
|
||||
case VN_CHR: {
|
||||
struct chrdev *chr = vn->dev;
|
||||
_assert(chr);
|
||||
if (chr->type == CHRDEV_TTY && (chr->tc.c_iflag & ICANON)) {
|
||||
if (chr->type == CHRDEV_TTY && (chr->tc.c_lflag & ICANON)) {
|
||||
return (chr->buffer.flags & (RING_SIGNAL_RET | RING_SIGNAL_EOF | RING_SIGNAL_BRK));
|
||||
} else {
|
||||
return !!ring_readable(&chr->buffer);
|
||||
|
||||
Reference in New Issue
Block a user