From 844f55c7d0f55542efd73574ea13a18d29167f84 Mon Sep 17 00:00:00 2001 From: Drew Galbraith Date: Sat, 24 Feb 2024 15:25:00 -0800 Subject: [PATCH] [Mammoth/Voyageurs] Add shift modifiers for scancodes. --- lib/mammoth/input/keyboard.cpp | 127 +++++++-------------- lib/mammoth/input/keyboard.h | 20 +--- lib/mammoth/ipc/port_client.cpp | 5 + lib/mammoth/ipc/port_client.h | 1 + lib/mammoth/ipc/port_server.cpp | 8 ++ lib/mammoth/ipc/port_server.h | 1 + sys/voyageurs/keyboard/keyboard_driver.cpp | 8 +- sys/voyageurs/keyboard/keyboard_driver.h | 2 +- 8 files changed, 65 insertions(+), 107 deletions(-) diff --git a/lib/mammoth/input/keyboard.cpp b/lib/mammoth/input/keyboard.cpp index bd2d905..f0ab639 100644 --- a/lib/mammoth/input/keyboard.cpp +++ b/lib/mammoth/input/keyboard.cpp @@ -55,71 +55,54 @@ Thread KeyboardListenerBase::Listen() { void KeyboardListenerBase::ListenLoop() { while (true) { - auto scancode_or = server_.RecvChar(); + auto scancode_or = server_.RecvUint16(); if (!scancode_or.ok()) { check(scancode_or.error()); } - uint8_t scancode = scancode_or.value(); + uint16_t scancode = scancode_or.value(); - if (scancode == 0xE0) { - extended_on_ = true; - continue; - } - - Keycode k = ScancodeToKeycode(scancode); - Action a = ScancodeToAction(scancode); - HandleKeycode(k, a); + Keycode k = ScancodeToKeycode(scancode & 0xFF); + uint8_t modifiers = (scancode >> 8) & 0xFF; + HandleKeycode(k, modifiers); } } -void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) { +void KeyboardListenerBase::HandleKeycode(Keycode code, uint8_t modifiers) { char c = '\0'; - if (action == kPressed) { - if (code >= kA && code <= kZ) { - if (IsShift()) { - const char* alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - c = alpha[code - kA]; + if (code >= kA && code <= kZ) { + if (IsShift(modifiers)) { + const char* alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + c = alpha[code - kA]; - } else { - const char* alpha = "abcdefghijklmnopqrstuvwxyz"; - c = alpha[code - kA]; - } - } else if (code >= k1 && code <= k0) { - if (IsShift()) { - const char* num = "!@#$%^&*()"; - c = num[code - k1]; - } else { - const char* num = "1234567890"; - c = num[code - k1]; - } - } else if (code >= kMinus && code <= kBacktick) { - if (IsShift()) { - const char* sym = "_+{}|?:\"<>~"; - c = sym[code - kMinus]; - } else { - const char* sym = "-=[]\\/;',.`"; - c = sym[code - kMinus]; - } - } else if (code == kEnter) { - c = '\n'; - } else if (code == kSpace) { - c = ' '; - } else if (code == kTab) { - c = '\t'; - } else if (code == kBackspace) { - c = '\b'; - } else if (code == kLShift) { - lshift_ = true; - } else if (code == kRShift) { - rshift_ = true; + } else { + const char* alpha = "abcdefghijklmnopqrstuvwxyz"; + c = alpha[code - kA]; } - } else if (action == kReleased) { - if (code == kLShift) { - lshift_ = false; - } else if (code == kRShift) { - rshift_ = false; + } else if (code >= k1 && code <= k0) { + if (IsShift(modifiers)) { + const char* num = "!@#$%^&*()"; + c = num[code - k1]; + } else { + const char* num = "1234567890"; + c = num[code - k1]; } + } else if (code >= kMinus && code <= kBacktick) { + if (IsShift(modifiers)) { + const char* sym = "_+{}|?:\"<>~"; + c = sym[code - kMinus]; + } else { + const char* sym = "-=[]\\/;',.`"; + c = sym[code - kMinus]; + } + } else if (code == kEnter) { + c = '\n'; + } else if (code == kSpace) { + c = ' '; + } else if (code == kTab) { + c = '\t'; + } else if (code == kBackspace) { + c = '\b'; } if (c != '\0') { @@ -127,35 +110,7 @@ void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) { } } -Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) { - // Cancel out the released bit. - scancode &= 0x7F; - if (extended_on_) { - extended_on_ = false; - - switch (scancode) { - case 0x1D: - return kRCtrl; - case 0x38: - return kRAlt; - case 0x48: - return kUp; - case 0x4B: - return kLeft; - case 0x4D: - return kRight; - case 0x50: - return kDown; - case 0x53: - return kDelete; - case 0x5B: - return kSuper; - } - dbgln("Unknown extended scancode {x}", scancode); - - return kUnknownKeycode; - } - +Keycode KeyboardListenerBase::ScancodeToKeycode(uint16_t scancode) { switch (scancode) { case 0x04: return kA; @@ -257,8 +212,10 @@ Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) { return kBacktick; case 0x36: return kComma; - case 0x38: + case 0x37: return kPeriod; + case 0x38: + return kFSlash; case 0x39: return kEsc; // Capslock } @@ -268,8 +225,4 @@ Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) { return kUnknownKeycode; } -Action KeyboardListenerBase::ScancodeToAction(uint8_t scancode) { - return (scancode & 0x80) ? kReleased : kPressed; -} - } // namespace mmth diff --git a/lib/mammoth/input/keyboard.h b/lib/mammoth/input/keyboard.h index cba2d18..5dfa50b 100644 --- a/lib/mammoth/input/keyboard.h +++ b/lib/mammoth/input/keyboard.h @@ -78,12 +78,6 @@ enum Keycode { kRight = 0x5B, }; -enum Action { - kUnknownAction, - kPressed, - kReleased, -}; - class KeyboardListenerBase { public: KeyboardListenerBase(); @@ -99,7 +93,7 @@ class KeyboardListenerBase { // Override this to recieve all raw keycodes. By default // this function will try to translate each keycode into // a printable character and call HandleCharacter. - virtual void HandleKeycode(Keycode code, Action action); + virtual void HandleKeycode(Keycode code, uint8_t modifiers); // This function is called by the default HandleKeycode // implementation if you do not override it. If it recieves @@ -109,15 +103,11 @@ class KeyboardListenerBase { private: PortServer server_; - bool extended_on_ = false; + Keycode ScancodeToKeycode(uint16_t scancode); - bool lshift_ = false; - bool rshift_ = false; - - Keycode ScancodeToKeycode(uint8_t scancode); - Action ScancodeToAction(uint8_t scancode); - - bool IsShift() { return lshift_ || rshift_; } + bool IsShift(uint8_t modifiers) { + return (modifiers & 0x2) || (modifiers & 0x20); + } }; } // namespace mmth diff --git a/lib/mammoth/ipc/port_client.cpp b/lib/mammoth/ipc/port_client.cpp index 8bf1156..db6c60f 100644 --- a/lib/mammoth/ipc/port_client.cpp +++ b/lib/mammoth/ipc/port_client.cpp @@ -20,6 +20,11 @@ glcr::ErrorCode PortClient::WriteByte(uint8_t byte) { ZPortSend(port_cap_, 1, &byte, 0, nullptr)); } +glcr::ErrorCode PortClient::Write(uint16_t data) { + return static_cast( + ZPortSend(port_cap_, 2, &data, 0, nullptr)); +} + glcr::ErrorCode PortClient::Write(uint64_t data) { return static_cast( ZPortSend(port_cap_, 8, &data, 0, nullptr)); diff --git a/lib/mammoth/ipc/port_client.h b/lib/mammoth/ipc/port_client.h index c4fc222..a633357 100644 --- a/lib/mammoth/ipc/port_client.h +++ b/lib/mammoth/ipc/port_client.h @@ -19,6 +19,7 @@ class PortClient { glcr::ErrorCode WriteString(glcr::String str, z_cap_t cap); glcr::ErrorCode WriteByte(uint8_t byte); + glcr::ErrorCode Write(uint16_t data); glcr::ErrorCode Write(uint64_t data); z_cap_t cap() { return port_cap_; } diff --git a/lib/mammoth/ipc/port_server.cpp b/lib/mammoth/ipc/port_server.cpp index 4643143..f81e3b8 100644 --- a/lib/mammoth/ipc/port_server.cpp +++ b/lib/mammoth/ipc/port_server.cpp @@ -55,4 +55,12 @@ glcr::ErrorOr PortServer::RecvChar() { return byte; } +glcr::ErrorOr PortServer::RecvUint16() { + uint64_t bytes = 2; + uint64_t caps = 0; + uint16_t data; + RET_ERR(ZPortRecv(port_cap_, &bytes, &data, &caps, nullptr)); + return data; +} + } // namespace mmth diff --git a/lib/mammoth/ipc/port_server.h b/lib/mammoth/ipc/port_server.h index 9e46599..acc5430 100644 --- a/lib/mammoth/ipc/port_server.h +++ b/lib/mammoth/ipc/port_server.h @@ -19,6 +19,7 @@ class PortServer { glcr::ErrorCode PollForIntCap(uint64_t* msg, uint64_t* cap); glcr::ErrorOr RecvChar(); + glcr::ErrorOr RecvUint16(); z_cap_t cap() { return port_cap_; } diff --git a/sys/voyageurs/keyboard/keyboard_driver.cpp b/sys/voyageurs/keyboard/keyboard_driver.cpp index 43f921f..fc4f1d1 100644 --- a/sys/voyageurs/keyboard/keyboard_driver.cpp +++ b/sys/voyageurs/keyboard/keyboard_driver.cpp @@ -42,6 +42,7 @@ void KeyboardDriver::InterruptLoop() { } void KeyboardDriver::ProcessInput(uint64_t input) { + uint16_t modifiers = (input & 0xFF) << 8; uint64_t new_bitmap = 0; for (uint8_t i = 2; i < 8; i++) { uint8_t code = (input >> (8 * i)) & 0xFF; @@ -54,15 +55,14 @@ void KeyboardDriver::ProcessInput(uint64_t input) { uint64_t bit = 1 << code; new_bitmap |= bit; if ((bitmap_ & bit) != bit) { - SendKeypress(code); + SendKeypress(modifiers | code); } } bitmap_ = new_bitmap; } -void KeyboardDriver::SendKeypress(uint8_t scancode) { - dbgln("{x}", scancode); +void KeyboardDriver::SendKeypress(uint16_t scancode) { for (mmth::PortClient& client : listeners_) { - client.WriteByte(scancode); + client.Write(scancode); } } diff --git a/sys/voyageurs/keyboard/keyboard_driver.h b/sys/voyageurs/keyboard/keyboard_driver.h index 84715e1..54dee91 100644 --- a/sys/voyageurs/keyboard/keyboard_driver.h +++ b/sys/voyageurs/keyboard/keyboard_driver.h @@ -25,5 +25,5 @@ class KeyboardDriver { uint64_t bitmap_ = 0; void ProcessInput(uint64_t input); - void SendKeypress(uint8_t scancode); + void SendKeypress(uint16_t scancode); };