input: Implement console input handling and add shell for real this time
Self explanatory, we finally have a working ish shell Now we need to do some more stuff or something, probably work on a fork or something Signed-off-by: kaguya <vpshinomiya@protonmail.com> Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Binary file not shown.
@@ -5,17 +5,50 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "mm/memory.h"
|
#include "mm/memory.h"
|
||||||
#include "libk/string.h"
|
#include "libk/string.h"
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ *
|
/* ------------------------------------------------------------------ *
|
||||||
* Event ring-buffer
|
* Event ring-buffer
|
||||||
* ------------------------------------------------------------------ */
|
* ------------------------------------------------------------------ */
|
||||||
#define INPUT_BUF_SIZE 512
|
#define INPUT_BUF_SIZE 512
|
||||||
|
#define CONSOLE_BUF_SIZE 256
|
||||||
|
|
||||||
|
static char s_console_buf[CONSOLE_BUF_SIZE];
|
||||||
|
static size_t s_console_rpos = 0;
|
||||||
|
static size_t s_console_wpos = 0;
|
||||||
|
|
||||||
static input_event_t s_buf[INPUT_BUF_SIZE];
|
static input_event_t s_buf[INPUT_BUF_SIZE];
|
||||||
static size_t s_rpos = 0;
|
static size_t s_rpos = 0;
|
||||||
static size_t s_wpos = 0;
|
static size_t s_wpos = 0;
|
||||||
static spinlock_t s_lock = SPINLOCK_INIT;
|
static spinlock_t s_lock = SPINLOCK_INIT;
|
||||||
|
|
||||||
|
/* Called from IRQ context */
|
||||||
|
void input_push_char(char c)
|
||||||
|
{
|
||||||
|
spinlock_acquire_or_wait(&s_lock);
|
||||||
|
size_t next = (s_console_wpos + 1) % CONSOLE_BUF_SIZE;
|
||||||
|
if (next != s_console_rpos) { /* drop if full */
|
||||||
|
s_console_buf[s_console_wpos] = c;
|
||||||
|
s_console_wpos = next;
|
||||||
|
}
|
||||||
|
spinlock_drop(&s_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
int input_read_console(void *buf, size_t len)
|
||||||
|
{
|
||||||
|
uint8_t *p = buf;
|
||||||
|
size_t count = 0;
|
||||||
|
|
||||||
|
spinlock_acquire_or_wait(&s_lock);
|
||||||
|
while (count < len && s_console_rpos != s_console_wpos) {
|
||||||
|
p[count++] = s_console_buf[s_console_rpos];
|
||||||
|
s_console_rpos = (s_console_rpos + 1) % CONSOLE_BUF_SIZE;
|
||||||
|
}
|
||||||
|
spinlock_drop(&s_lock);
|
||||||
|
|
||||||
|
return (int)count; /* 0 = no data yet (non-blocking) */
|
||||||
|
}
|
||||||
|
|
||||||
static void push_event(const input_event_t *ev)
|
static void push_event(const input_event_t *ev)
|
||||||
{
|
{
|
||||||
spinlock_acquire_or_wait(&s_lock);
|
spinlock_acquire_or_wait(&s_lock);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ------------------------------------------------------------------ *
|
/* ------------------------------------------------------------------ *
|
||||||
* Generic input event types
|
* Generic input event types
|
||||||
@@ -53,6 +54,9 @@ void input_push_mouse_rel(int16_t dx, int16_t dy);
|
|||||||
void input_push_mouse_btn(uint8_t button, bool pressed);
|
void input_push_mouse_btn(uint8_t button, bool pressed);
|
||||||
void input_push_mouse_wheel(int8_t delta);
|
void input_push_mouse_wheel(int8_t delta);
|
||||||
|
|
||||||
|
void input_push_char(char c);
|
||||||
|
int input_read_console(void *buf, size_t len);
|
||||||
|
|
||||||
/* Consumer API */
|
/* Consumer API */
|
||||||
bool input_poll(input_event_t *out); /* non-blocking; false if empty */
|
bool input_poll(input_event_t *out); /* non-blocking; false if empty */
|
||||||
bool input_has_event(void);
|
bool input_has_event(void);
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include "arch/x86_64/sys/ioapic.h"
|
#include "arch/x86_64/sys/ioapic.h"
|
||||||
#include "arch/x86_64/sys/apic.h"
|
#include "arch/x86_64/sys/apic.h"
|
||||||
#include "libk/stdio.h"
|
#include "libk/stdio.h"
|
||||||
|
#include "drivers/video/render.h"
|
||||||
|
|
||||||
/* ── PS/2 I/O ports ───────────────────────────────────────────────────────── */
|
/* ── PS/2 I/O ports ───────────────────────────────────────────────────────── */
|
||||||
#define PS2_DATA_PORT 0x60 /* Read: scancode / Write: command data */
|
#define PS2_DATA_PORT 0x60 /* Read: scancode / Write: command data */
|
||||||
@@ -150,9 +151,15 @@ void ps2_kbd_handler(Registers *regs)
|
|||||||
/* ── Push event ──────────────────────────────────────────────────── */
|
/* ── Push event ──────────────────────────────────────────────────── */
|
||||||
input_push_key(scancode, ascii, pressed);
|
input_push_key(scancode, ascii, pressed);
|
||||||
|
|
||||||
/* Optionally echo to debug port for development */
|
|
||||||
if (pressed && ascii) {
|
if (pressed && ascii) {
|
||||||
/* e9_putc(ascii); ← uncomment if you have e9 debug output */
|
input_push_char(ascii);
|
||||||
|
|
||||||
|
if (ascii == '\b') {
|
||||||
|
backspace();
|
||||||
|
} else {
|
||||||
|
putchar(ascii);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include "libk/stdio.h"
|
#include "libk/stdio.h"
|
||||||
#include "mm/memory.h"
|
#include "mm/memory.h"
|
||||||
#include "libk/string.h"
|
#include "libk/string.h"
|
||||||
|
#include "drivers/input/input.h"
|
||||||
|
|
||||||
static spinlock_t s_vfs_lock = SPINLOCK_INIT;
|
static spinlock_t s_vfs_lock = SPINLOCK_INIT;
|
||||||
static vfs_file_t vfs_fd_table[VFS_MAX_FDS];
|
static vfs_file_t vfs_fd_table[VFS_MAX_FDS];
|
||||||
@@ -111,6 +112,10 @@ int VFS_Read_internal(fd_t fd, uint8_t* buf, size_t size)
|
|||||||
if (fd < 0 || fd >= VFS_MAX_FDS)
|
if (fd < 0 || fd >= VFS_MAX_FDS)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (fd == VFS_FD_STDIN) {
|
||||||
|
return input_read_console(buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
vfs_file_t* file = &vfs_fd_table[fd];
|
vfs_file_t* file = &vfs_fd_table[fd];
|
||||||
|
|
||||||
if (!file->used)
|
if (!file->used)
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
+84
-1
@@ -1,6 +1,7 @@
|
|||||||
#include "../include/syscalls.h"
|
#include "../include/syscalls.h"
|
||||||
|
|
||||||
#define STDOUT 1
|
#define STDIN 0
|
||||||
|
#define STDOUT 1
|
||||||
|
|
||||||
unsigned strlen(const char* str)
|
unsigned strlen(const char* str)
|
||||||
{
|
{
|
||||||
@@ -13,6 +14,64 @@ unsigned strlen(const char* str)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int strcmp(const char* a, const char* b)
|
||||||
|
{
|
||||||
|
while (*a && (*a == *b)) {
|
||||||
|
a++;
|
||||||
|
b++;
|
||||||
|
}
|
||||||
|
return *(unsigned char*)a - *(unsigned char*)b;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print(const char* s)
|
||||||
|
{
|
||||||
|
syscall(SYS_WRITE, STDOUT, (unsigned long)s, strlen(s), 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void readline(char* buf, unsigned long max)
|
||||||
|
{
|
||||||
|
unsigned long i = 0;
|
||||||
|
|
||||||
|
while (i < max - 1)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
long n = syscall(SYS_READ, STDIN, (unsigned long)&c, 1, 0, 0, 0);
|
||||||
|
|
||||||
|
if (n <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (c == '\n')
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (c == '\b') {
|
||||||
|
if (i > 0) i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[i++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[i] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cat(const char* path)
|
||||||
|
{
|
||||||
|
unsigned char buf[256];
|
||||||
|
|
||||||
|
long fd = syscall(SYS_OPEN, (unsigned long)path, 0, 0, 0, 0, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
print("cat: cannot open file\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
long n = syscall(SYS_READ, fd, (unsigned long)buf, sizeof(buf), 0, 0, 0);
|
||||||
|
syscall(SYS_CLOSE, fd, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
if (n > 0)
|
||||||
|
syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
const unsigned char* path = "/qwerty.txt";
|
const unsigned char* path = "/qwerty.txt";
|
||||||
@@ -41,6 +100,30 @@ void main()
|
|||||||
// ── print buffer to stdout ───────────────
|
// ── print buffer to stdout ───────────────
|
||||||
syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0);
|
syscall(SYS_WRITE, STDOUT, (unsigned long)buf, n, 0, 0, 0);
|
||||||
|
|
||||||
|
char line[128];
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
print("> ");
|
||||||
|
|
||||||
|
readline(line, sizeof(line));
|
||||||
|
|
||||||
|
if (strcmp(line, "exit") == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// simple "cat <path>"
|
||||||
|
if (line[0] == 'c' && line[1] == 'a' && line[2] == 't' && line[3] == ' ')
|
||||||
|
{
|
||||||
|
cat(&line[4]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line[0] != '\0')
|
||||||
|
print("Unknown command\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1);
|
||||||
|
|
||||||
// ── done ────────────────────────────────
|
// ── done ────────────────────────────────
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user