77 lines
2.2 KiB
C++
77 lines
2.2 KiB
C++
/*
|
|
* Keyboard.hpp
|
|
* PS/2 Keyboard driver
|
|
* Copyright (c) 2025 Daniel Hammer
|
|
*/
|
|
|
|
#pragma once
|
|
#include <cstdint>
|
|
|
|
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;
|
|
}
|
|
|
|
};
|