Files
KirkOS/oldsrc/input/input.c
T
2026-05-18 04:02:59 -04:00

150 lines
3.7 KiB
C

#include "drivers/input/input.h"
#include "mp/spinlock.h"
#include "libk/stdio.h"
#include "fs/vfs.h"
#include <stddef.h>
#include "mm/memory.h"
#include "libk/string.h"
#include <stddef.h>
#include "libk/debug.h"
/* ------------------------------------------------------------------ *
* Event ring-buffer
* ------------------------------------------------------------------ */
#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 size_t s_rpos = 0;
static size_t s_wpos = 0;
static spinlock_t s_lock = SPINLOCK_INIT;
/* Called from IRQ context */
void input_push_char(char c)
{
uint64_t flags;
spinlock_acquire_irqsave(&s_lock, &flags);
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_release_irqrestore(&s_lock, flags);
}
int input_read_console(void *buf, size_t len)
{
uint8_t *p = buf;
size_t count = 0;
uint64_t flags;
spinlock_acquire_irqsave(&s_lock, &flags);
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_release_irqrestore(&s_lock, flags);
return (int)count;
}
static void push_event(const input_event_t *ev)
{
spinlock_acquire_or_wait(&s_lock);
size_t next = (s_wpos + 1) % INPUT_BUF_SIZE;
if (next != s_rpos) { /* drop if full */
s_buf[s_wpos] = *ev;
s_wpos = next;
}
spinlock_drop(&s_lock);
}
bool input_poll(input_event_t *out)
{
spinlock_acquire_or_wait(&s_lock);
if (s_rpos == s_wpos) {
spinlock_drop(&s_lock);
return false;
}
*out = s_buf[s_rpos];
s_rpos = (s_rpos + 1) % INPUT_BUF_SIZE;
spinlock_drop(&s_lock);
return true;
}
bool input_has_event(void)
{
spinlock_acquire_or_wait(&s_lock);
bool has = (s_rpos != s_wpos);
spinlock_drop(&s_lock);
return has;
}
/* ------------------------------------------------------------------ *
* Driver-facing helpers
* ------------------------------------------------------------------ */
void input_push_key(uint8_t scancode, char ascii, bool pressed)
{
input_event_t ev = {
.type = INPUT_EV_KEY,
.key = { .scancode = scancode, .ascii = ascii, .pressed = pressed },
};
push_event(&ev);
}
void input_push_mouse_rel(int16_t dx, int16_t dy)
{
input_event_t ev = { .type = INPUT_EV_MOUSE_REL, .rel = { dx, dy } };
push_event(&ev);
}
void input_push_mouse_btn(uint8_t button, bool pressed)
{
input_event_t ev = {
.type = INPUT_EV_MOUSE_BTN,
.btn = { .button = button, .pressed = pressed },
};
push_event(&ev);
}
void input_push_mouse_wheel(int8_t delta)
{
input_event_t ev = { .type = INPUT_EV_MOUSE_WHEEL, .wheel = { delta } };
push_event(&ev);
}
static int dev_input_read(void *buf, size_t len)
{
size_t count = 0;
while (count + sizeof(input_event_t) <= len) {
input_event_t ev;
if (!input_poll(&ev)) break;
memcpy((uint8_t*)buf + count, &ev, sizeof(ev));
count += sizeof(ev);
}
return (int)count;
}
static int dev_input_write(const void *buf, size_t len)
{
(void)buf; (void)len;
return -1; /* read-only */
}
void input_register_devnodes(void)
{
VFS_RegisterCharDev("/dev/input/event0", dev_input_read, dev_input_write);
}
void input_init(void)
{
input_register_devnodes();
kprintf("input: subsystem initialized\n");
}