major refactorings
Signed-off-by: kaguya3311 <kaguya3311@national.shitposting.agency>
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
#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");
|
||||
}
|
||||
Reference in New Issue
Block a user