mirror of
https://github.com/JannisHeydemann/BoredOS.git
synced 2026-05-30 10:26:59 +00:00
feature(input): implement keyboard layouts and utf-8 input subsystem
* Adding keyboard layout (backend) * Update settings.c with new keyboard tab * Fixing keyboard icon && Fixing long loading time in settings.c * Refactor of key handling for a larger compatibility with the keyboard layout * Adding keyboard handler * Udating ps2.c with the new logic * Updating WM/kernel/userland with the new input system * Fixing keycode range && Updating dead keys handling * Add comments for explanation * Update notepad & vm.c to parse utf-8 * Adding utf-8 parsing utils in libc && Update notepad.c * Adding icon for icon settings * Fixing a warning with double definition * Adding new kb kayout: QWERTZ and DVORAK && Update new layout instrauction * Add documentation for keyboard input subsystem This document outlines the architecture and design of the input subsystem, focusing on keyboard input processing, driver responsibilities, keycode representation, and keymap functionality. --------- Co-authored-by: boreddevnl <chris@boreddev.nl>
This commit is contained in:
81
src/mem/vm.c
81
src/mem/vm.c
@@ -11,15 +11,8 @@
|
||||
#include "ps2.h"
|
||||
#include "kutils.h"
|
||||
#include "io.h"
|
||||
|
||||
// --- Scancode Map (Set 1) ---
|
||||
static char vm_scancode_map[128] = {
|
||||
0, 27, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
|
||||
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
|
||||
0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0,
|
||||
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*',
|
||||
0, ' ', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
#include "input/keymap.h"
|
||||
#include "input/keyboard.h"
|
||||
|
||||
// VM State
|
||||
static int stack[VM_STACK_SIZE];
|
||||
@@ -97,8 +90,22 @@ static void vm_syscall(int id) {
|
||||
push(0);
|
||||
break;
|
||||
case VM_SYS_PRINT_CHAR: {
|
||||
char c = (char)pop();
|
||||
char s[2] = {c, 0};
|
||||
uint32_t cp = (uint32_t)pop();
|
||||
char s[5] = {0};
|
||||
|
||||
if (cp < 0x80) {
|
||||
s[0] = cp;
|
||||
} else if (cp < 0x800) {
|
||||
s[0] = 0xC0 | (cp >> 6);
|
||||
s[1] = 0x80 | (cp & 0x3F);
|
||||
} else if (cp < 0x10000) {
|
||||
s[0] = 0xE0 | (cp >> 12);
|
||||
s[1] = 0x80 | ((cp >> 6) & 0x3F);
|
||||
s[2] = 0x80 | (cp & 0x3F);
|
||||
} else {
|
||||
s[0] = '?';
|
||||
}
|
||||
|
||||
cmd_write(s);
|
||||
push(0);
|
||||
break;
|
||||
@@ -121,15 +128,32 @@ static void vm_syscall(int id) {
|
||||
break;
|
||||
case VM_SYS_GETCHAR: {
|
||||
int c = 0;
|
||||
// Blocking read for a valid key press
|
||||
bool ext = false;
|
||||
// Wait for a key press and return the ASCII code
|
||||
while (1) {
|
||||
if ((inb(0x64) & 1)) { // Data available
|
||||
if ((inb(0x64) & 1)) { // Data available in keyboard controller
|
||||
uint8_t sc = inb(0x60);
|
||||
if (!(sc & 0x80)) { // Key press
|
||||
if (sc < 128) {
|
||||
c = vm_scancode_map[sc];
|
||||
if (c) break;
|
||||
|
||||
if (sc == 0xE0) { // Extended scancode prefix
|
||||
ext = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!(sc & 0x80)) { // Key press (not release)
|
||||
uint16_t keycode = keyboard_keycode_from_set1((uint8_t)(sc & 0x7F), ext); // Get keycode and reset
|
||||
ext = false;
|
||||
|
||||
if (keycode != KEY_NONE) {
|
||||
uint32_t mods = keyboard_get_modifiers();
|
||||
keymap_result_t r = keymap_translate_keycode(keycode, mods);
|
||||
// Only return valid text characters, ignore modifiers and dead keys
|
||||
if (r.is_text && !r.is_dead && r.codepoint >= 32 && r.codepoint != 127) {
|
||||
c = (int)r.codepoint;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ext = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -545,7 +569,26 @@ int vm_exec(const uint8_t *code, int code_size) {
|
||||
case OP_MUL: push(pop() * pop()); break;
|
||||
case OP_DIV: { int b=pop(); int a=pop(); push(b==0?0:a/b); } break;
|
||||
case OP_PRINT: cmd_write_int(pop()); cmd_write("\n"); break;
|
||||
case OP_PRITC: { char c=(char)pop(); char s[2]={c,0}; cmd_write(s); } break;
|
||||
case OP_PRITC: {
|
||||
uint32_t cp = (uint32_t)pop();
|
||||
char s[5] = {0};
|
||||
|
||||
if (cp < 0x80) {
|
||||
s[0] = (char)cp;
|
||||
} else if (cp < 0x800) {
|
||||
s[0] = (char)(0xC0 | (cp >> 6));
|
||||
s[1] = (char)(0x80 | (cp & 0x3F));
|
||||
} else if (cp < 0x10000) {
|
||||
s[0] = (char)(0xE0 | (cp >> 12));
|
||||
s[1] = (char)(0x80 | ((cp >> 6) & 0x3F));
|
||||
s[2] = (char)(0x80 | (cp & 0x3F));
|
||||
} else {
|
||||
s[0] = '?';
|
||||
}
|
||||
|
||||
cmd_write(s);
|
||||
break;
|
||||
}
|
||||
case OP_JMP: {
|
||||
int addr = 0;
|
||||
addr |= memory[pc++];
|
||||
@@ -601,4 +644,4 @@ int vm_exec(const uint8_t *code, int code_size) {
|
||||
}
|
||||
wm_custom_paint_hook = NULL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user