add: hold down key && core: create get_key to simplify keyboard usage

This commit is contained in:
Starnakin 2024-10-09 22:58:06 +02:00
parent fc8bc6a495
commit 06ade25a46
5 changed files with 54 additions and 48 deletions

View File

@ -103,3 +103,5 @@ struct key_event {
uint8_t c; uint8_t c;
uint8_t scan_code; uint8_t scan_code;
}; };
struct key_event get_key(void);

View File

@ -59,4 +59,3 @@ void terminal_set_default_bg_color(uint8_t fg_color);
void terminal_change_default_fg_color(uint8_t color); void terminal_change_default_fg_color(uint8_t color);
uint8_t terminal_get_default_color(void); uint8_t terminal_get_default_color(void);
uint8_t terminal_get_char(int column, int row); uint8_t terminal_get_char(int column, int row);
char *get_line(void);

View File

@ -1,53 +1,29 @@
#include "keyboard.h"
#include "drivers.h" #include "drivers.h"
#include "interrupts.h" #include "interrupts.h"
#include "kprintf.h" #include "kprintf.h"
#include "shell.h" #include "shell.h"
#include "string.h" #include "string.h"
#include "terminal.h" #include "terminal.h"
#include <stdbool.h>
#include <stdint.h> #include <stdint.h>
extern struct screen *screen; extern struct screen *screen;
int line_status = READING; static bool new_input_indicator = false;
static struct key_event new_input = {};
void keyboard_handler(struct registers *regs) void keyboard_handler(struct registers *regs)
{ {
size_t i = 0; new_input_indicator = true;
struct key_event ev; new_input = terminal_getkey();
(void)regs;
ev = terminal_getkey();
char *buf = screen->line;
i = strlen(screen->line);
if (ev.c == '\n') {
kprintf("\n");
screen->line[i] = '\0';
line_status = NEWLINE;
return;
}
const size_t size = sizeof(screen->line);
if (ev.scan_code == KEY_BACKSPACE && i) {
buf[--i] = '\0';
move_cursor(LEFT);
terminal_putchar(' ');
move_cursor(LEFT);
} else if (ev.scan_code == KEY_TAB && i) {
auto_complete();
} else if (ev.c && i < size - 1) {
kprintf("%c", ev.c);
buf[i++] = ev.c;
}
if (i >= size) {
kprintf("\n");
screen->line[i] = '\0';
line_status = NEWLINE;
}
} }
char *get_line(void) struct key_event get_key(void)
{ {
while (line_status != NEWLINE)
while (!new_input_indicator)
; ;
line_status = READING; new_input_indicator = false;
return screen->line; return new_input;
} }

View File

@ -75,11 +75,44 @@ void auto_complete(void)
} }
} }
void shell_init(void) static char *get_line(void)
{ {
char *line; size_t i = 0;
struct key_event ev;
while (1) {
ev = get_key();
// kprintf("%d %d\n", ev.scan_code, ev.c);
if (ev.c == '\n')
break;
char *buf = screen->line;
i = strlen(screen->line);
const size_t size = sizeof(screen->line);
if (ev.scan_code) {
if (ev.scan_code == KEY_BACKSPACE && i) {
buf[--i] = '\0';
move_cursor(LEFT);
terminal_putchar(' ');
move_cursor(LEFT);
} else if (ev.scan_code == KEY_TAB && i) {
auto_complete();
} else if (ev.c && i < size - 1) {
kprintf("%c", ev.c);
buf[i++] = ev.c;
}
if (i >= size)
break;
}
}
kprintf("\n");
screen->line[i] = '\0';
}
void shell_init()
{
while (1) {
kprintf(PROMPT); kprintf(PROMPT);
while ((line = get_line())) { get_line();
bool invalid = true; bool invalid = true;
for (unsigned i = 0; i < NB_CMDS; i++) { for (unsigned i = 0; i < NB_CMDS; i++) {
if (!strncmp(cmds[i].name, screen->line, if (!strncmp(cmds[i].name, screen->line,
@ -96,6 +129,5 @@ void shell_init(void)
kprintf(KERN_WARNING "invalid command: %s\n", kprintf(KERN_WARNING "invalid command: %s\n",
screen->line); screen->line);
memset(screen->line, '\0', sizeof(screen->line)); memset(screen->line, '\0', sizeof(screen->line));
kprintf(PROMPT);
} }
} }

View File

@ -7,7 +7,6 @@
struct key_event terminal_getkey(void) struct key_event terminal_getkey(void)
{ {
static bool caps_mode = false; static bool caps_mode = false;
static uint8_t prev_scan_code = 0;
struct key_event ev = {0}; struct key_event ev = {0};
uint8_t scan_code; uint8_t scan_code;
@ -20,13 +19,11 @@ struct key_event terminal_getkey(void)
else if (scan_code == KEY_RIGHT_SHIFT + 128 || else if (scan_code == KEY_RIGHT_SHIFT + 128 ||
scan_code == KEY_LEFT_SHIFT + 128) scan_code == KEY_LEFT_SHIFT + 128)
caps_mode = false; caps_mode = false;
else if (scan_code != prev_scan_code && prev_scan_code != 0) { if (scan_code < 128) {
if (scan_code < 128 && keymap[scan_code])
ev.c = keymap[scan_code][caps_mode]; ev.c = keymap[scan_code][caps_mode];
if (scan_code >= KEY_F1 && scan_code <= KEY_F10) if (scan_code >= KEY_F1 && scan_code <= KEY_F10)
terminal_set_screen(scan_code - KEY_F1); terminal_set_screen(scan_code - KEY_F1);
}
prev_scan_code = scan_code;
ev.scan_code = scan_code; ev.scan_code = scan_code;
}
return ev; return ev;
} }