summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2017-05-31 23:55:24 +0200
committerRichard Braun <rbraun@sceen.net>2017-05-31 23:55:24 +0200
commit5d495c877e78be8dbabdaf631c9c02a72190d6a9 (patch)
tree874fe42a3b3a3cc7b9faf23e748995ab04098e2f
parent2133f7690eeaea94d521a69eba6812f6ddd45f6d (diff)
x86/{atcons,atkbd,cga}: rework escape sequence handling
-rw-r--r--arch/x86/machine/atcons.c121
-rw-r--r--arch/x86/machine/atcons.h8
-rw-r--r--arch/x86/machine/atkbd.c41
-rw-r--r--arch/x86/machine/cga.c15
-rw-r--r--arch/x86/machine/cga.h6
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 */