diff options
author | Richard Braun <rbraun@sceen.net> | 2017-05-31 23:55:24 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2017-05-31 23:55:24 +0200 |
commit | 5d495c877e78be8dbabdaf631c9c02a72190d6a9 (patch) | |
tree | 874fe42a3b3a3cc7b9faf23e748995ab04098e2f | |
parent | 2133f7690eeaea94d521a69eba6812f6ddd45f6d (diff) |
x86/{atcons,atkbd,cga}: rework escape sequence handling
-rw-r--r-- | arch/x86/machine/atcons.c | 121 | ||||
-rw-r--r-- | arch/x86/machine/atcons.h | 8 | ||||
-rw-r--r-- | arch/x86/machine/atkbd.c | 41 | ||||
-rw-r--r-- | arch/x86/machine/cga.c | 15 | ||||
-rw-r--r-- | arch/x86/machine/cga.h | 6 |
5 files changed, 178 insertions, 13 deletions
diff --git a/arch/x86/machine/atcons.c b/arch/x86/machine/atcons.c index 223298c4..e1e14c62 100644 --- a/arch/x86/machine/atcons.c +++ b/arch/x86/machine/atcons.c @@ -15,19 +15,114 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#include <stdbool.h> +#include <string.h> + #include <kern/console.h> #include <kern/init.h> #include <machine/atcons.h> #include <machine/atkbd.h> #include <machine/cga.h> +#define ATCONS_ESC_SEQ_MAX_SIZE 8 + static struct console atcons_console; +typedef void (*atcons_esc_seq_fn_t)(void); + +struct atcons_esc_seq { + const char *str; + atcons_esc_seq_fn_t fn; +}; + +static bool atcons_escape; +static char atcons_esc_seq[ATCONS_ESC_SEQ_MAX_SIZE]; +static unsigned int atcons_esc_seq_index; + +static void +atcons_process_left(void) +{ + cga_cursor_left(); +} + +static void +atcons_process_right(void) +{ + cga_cursor_right(); +} + +static const struct atcons_esc_seq atcons_esc_seqs[] = { + { "[1D", atcons_process_left }, + { "[1C", atcons_process_right }, +}; + +static void +atcons_reset_esc_seq(void) +{ + atcons_escape = false; +} + +static int +atcons_esc_seq_lookup(const struct atcons_esc_seq **seqp) +{ + const struct atcons_esc_seq *seq; + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(atcons_esc_seqs); i++) { + seq = &atcons_esc_seqs[i]; + + if (strncmp(seq->str, atcons_esc_seq, atcons_esc_seq_index) == 0) { + if (strlen(seq->str) == atcons_esc_seq_index) { + *seqp = seq; + return 0; + } else { + return ERROR_AGAIN; + } + } + } + + return ERROR_SRCH; +} + +static void +atcons_process_esc_seq(char c) +{ + const struct atcons_esc_seq *seq; + int error; + + if (atcons_esc_seq_index >= sizeof(atcons_esc_seq)) { + atcons_reset_esc_seq(); + return; + } + + atcons_esc_seq[atcons_esc_seq_index] = c; + atcons_esc_seq_index++; + + error = atcons_esc_seq_lookup(&seq); + + if (error) { + if (error != ERROR_AGAIN) { + atcons_reset_esc_seq(); + } + } else { + seq->fn(); + atcons_reset_esc_seq(); + } +} + static void atcons_putc(struct console *console, char c) { (void)console; - cga_putc(c); + + if (c == '\e') { + atcons_escape = true; + atcons_esc_seq_index = 0; + } else if (atcons_escape) { + atcons_process_esc_seq(c); + } else { + cga_putc(c); + } } static const struct console_ops atcons_ops = { @@ -54,3 +149,27 @@ atcons_intr(const char *s) { console_intr(&atcons_console, s); } + +void +atcons_left(void) +{ + atcons_intr("\e[D"); +} + +void +atcons_bottom(void) +{ + atcons_intr("\e[B"); +} + +void +atcons_right(void) +{ + atcons_intr("\e[C"); +} + +void +atcons_up(void) +{ + atcons_intr("\e[A"); +} diff --git a/arch/x86/machine/atcons.h b/arch/x86/machine/atcons.h index ffe22dc9..d6923df2 100644 --- a/arch/x86/machine/atcons.h +++ b/arch/x86/machine/atcons.h @@ -41,4 +41,12 @@ void atcons_setup(void); */ void atcons_intr(const char *s); +/* + * Direction control processing functions. + */ +void atcons_left(void); +void atcons_bottom(void); +void atcons_right(void); +void atcons_up(void); + #endif /* _X86_ATCONS_H */ diff --git a/arch/x86/machine/atkbd.c b/arch/x86/machine/atkbd.c index 36e2ee3d..c5140c45 100644 --- a/arch/x86/machine/atkbd.c +++ b/arch/x86/machine/atkbd.c @@ -248,10 +248,10 @@ static const struct atkbd_key atkbd_e0_keys[] = { [0x7d] = { 0, ATKBD_KEY_PGUP }, [0x7a] = { 0, ATKBD_KEY_PGDOWN }, - [0x6b] = { 0, ATKBD_KEY_LEFT }, - [0x72] = { 0, ATKBD_KEY_BOTTOM }, - [0x74] = { 0, ATKBD_KEY_RIGHT }, - [0x75] = { 0, ATKBD_KEY_UP }, + [0x6b] = { ATKBD_KM_CTL, ATKBD_KEY_LEFT }, + [0x72] = { ATKBD_KM_CTL, ATKBD_KEY_BOTTOM }, + [0x74] = { ATKBD_KM_CTL, ATKBD_KEY_RIGHT }, + [0x75] = { ATKBD_KM_CTL, ATKBD_KEY_UP }, [0x4a] = { 0, ATKBD_KEY_KP_SLASH }, [0x5a] = { 0, ATKBD_KEY_KP_ENTER }, @@ -315,11 +315,6 @@ static const char *atkbd_chars[] = { [ATKBD_KEY_DELETE] = "\e[3~", - [ATKBD_KEY_LEFT] = "\e[D", - [ATKBD_KEY_BOTTOM] = "\e[B", - [ATKBD_KEY_RIGHT] = "\e[C", - [ATKBD_KEY_UP] = "\e[A", - [ATKBD_KEY_KP_SLASH] = "/", [ATKBD_KEY_KP_STAR] = "*", [ATKBD_KEY_KP_MINUS] = "-", @@ -655,6 +650,30 @@ atkbd_key_process_ctl(const struct atkbd_key *key) atkbd_toggle_capslock(); } break; + case ATKBD_KEY_LEFT: + if (!(atkbd_flags & ATKBD_KF_F0)) { + atcons_left(); + } + + break; + case ATKBD_KEY_BOTTOM: + if (!(atkbd_flags & ATKBD_KF_F0)) { + atcons_bottom(); + } + + break; + case ATKBD_KEY_RIGHT: + if (!(atkbd_flags & ATKBD_KF_F0)) { + atcons_right(); + } + + break; + case ATKBD_KEY_UP: + if (!(atkbd_flags & ATKBD_KF_F0)) { + atcons_up(); + } + + break; default: break; } @@ -689,7 +708,7 @@ atkbd_process_e0_code(uint8_t code) return; } - if (code >= ARRAY_SIZE(atkbd_keys)) { + if (code >= ARRAY_SIZE(atkbd_e0_keys)) { return; } @@ -708,7 +727,7 @@ atkbd_process_code(uint8_t code) return; } - if (code >= ARRAY_SIZE(atkbd_e0_keys)) { + if (code >= ARRAY_SIZE(atkbd_keys)) { return; } diff --git a/arch/x86/machine/cga.c b/arch/x86/machine/cga.c index 1ec80354..1d1cc4b2 100644 --- a/arch/x86/machine/cga.c +++ b/arch/x86/machine/cga.c @@ -133,7 +133,6 @@ cga_putc(char c) } else if (c == '\b') { if (cga_cursor > 0) { cga_cursor--; - ((uint16_t *)cga_memory)[cga_cursor] = CGA_BLANK; cga_set_cursor_position(cga_cursor); } } else if (c == '\t') { @@ -181,3 +180,17 @@ cga_setup(void) cga_cursor = cga_get_cursor_position(); } + +void +cga_cursor_left(void) +{ + cga_cursor--; + cga_set_cursor_position(cga_cursor); +} + +void +cga_cursor_right(void) +{ + cga_cursor++; + cga_set_cursor_position(cga_cursor); +} diff --git a/arch/x86/machine/cga.h b/arch/x86/machine/cga.h index f5a5d285..2310bc91 100644 --- a/arch/x86/machine/cga.h +++ b/arch/x86/machine/cga.h @@ -31,4 +31,10 @@ void cga_setup(void); */ void cga_putc(char c); +/* + * Cursor control functions. + */ +void cga_cursor_left(void); +void cga_cursor_right(void); + #endif /* _X86_CGA_H */ |