/* * Keyboard.hpp * PS/2 Keyboard driver * Copyright (c) 2025 Daniel Hammer */ #pragma once #include namespace Drivers::PS2::Keyboard { // Key event structure struct KeyEvent { uint8_t Scancode; char Ascii; bool Pressed; bool Shift; bool Ctrl; bool Alt; bool CapsLock; // Right Alt held. Reported separately from Alt so keyboard layouts can // use it as AltGr without swallowing left-Alt shortcuts. bool AltGr; // Key came from an E0-prefixed (extended) scancode. The prefix is not // part of Scancode, so without this flag keypad "/" is indistinguishable // from the main "/" key and layout translation would rewrite it. bool Extended; }; // Modifier key state struct ModifierState { bool LeftShift; bool RightShift; bool LeftCtrl; bool RightCtrl; bool LeftAlt; bool RightAlt; bool CapsLock; bool NumLock; bool ScrollLock; }; // Ring buffer size (must be power of 2) constexpr uint32_t KeyBufferSize = 256; void Initialize(); // Interrupt handler -- called from IRQ dispatch (EOI is sent automatically) void HandleIRQ(uint8_t irq, bool fromUser); // Public interface for consuming key events bool IsKeyAvailable(); KeyEvent GetKey(); char GetChar(); // Modifier state query const ModifierState& GetModifiers(); // Inject a key event from an external source (e.g., USB HID keyboard) void InjectKeyEvent(const KeyEvent& event); // Current Caps Lock state. Injecting drivers (USB HID) need this to // compute ASCII, since the lock is toggled centrally here. bool GetCapsLock(); // Current Num Lock state, owned here like Caps Lock. On (the default), the // keypad types digits; off, it acts as the navigation keys printed on it. bool GetNumLock(); // Set-1 scancodes of the keypad keys that are a digit/'.' with Num Lock on // and Home/arrows/PgUp/End/PgDn/Ins/Del with it off (not '-' and '+'). inline bool IsKeypadNavScancode(uint8_t keycode) { return keycode >= 0x47 && keycode <= 0x53 && keycode != 0x4A && keycode != 0x4E; } };