[Mammoth/Voyageurs] Add shift modifiers for scancodes.

This commit is contained in:
Drew Galbraith 2024-02-24 15:25:00 -08:00
parent a9351b222d
commit 844f55c7d0
8 changed files with 65 additions and 107 deletions

View File

@ -55,29 +55,23 @@ Thread KeyboardListenerBase::Listen() {
void KeyboardListenerBase::ListenLoop() { void KeyboardListenerBase::ListenLoop() {
while (true) { while (true) {
auto scancode_or = server_.RecvChar(); auto scancode_or = server_.RecvUint16();
if (!scancode_or.ok()) { if (!scancode_or.ok()) {
check(scancode_or.error()); check(scancode_or.error());
} }
uint8_t scancode = scancode_or.value(); uint16_t scancode = scancode_or.value();
if (scancode == 0xE0) { Keycode k = ScancodeToKeycode(scancode & 0xFF);
extended_on_ = true; uint8_t modifiers = (scancode >> 8) & 0xFF;
continue; HandleKeycode(k, modifiers);
}
Keycode k = ScancodeToKeycode(scancode);
Action a = ScancodeToAction(scancode);
HandleKeycode(k, a);
} }
} }
void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) { void KeyboardListenerBase::HandleKeycode(Keycode code, uint8_t modifiers) {
char c = '\0'; char c = '\0';
if (action == kPressed) {
if (code >= kA && code <= kZ) { if (code >= kA && code <= kZ) {
if (IsShift()) { if (IsShift(modifiers)) {
const char* alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; const char* alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
c = alpha[code - kA]; c = alpha[code - kA];
@ -86,7 +80,7 @@ void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) {
c = alpha[code - kA]; c = alpha[code - kA];
} }
} else if (code >= k1 && code <= k0) { } else if (code >= k1 && code <= k0) {
if (IsShift()) { if (IsShift(modifiers)) {
const char* num = "!@#$%^&*()"; const char* num = "!@#$%^&*()";
c = num[code - k1]; c = num[code - k1];
} else { } else {
@ -94,7 +88,7 @@ void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) {
c = num[code - k1]; c = num[code - k1];
} }
} else if (code >= kMinus && code <= kBacktick) { } else if (code >= kMinus && code <= kBacktick) {
if (IsShift()) { if (IsShift(modifiers)) {
const char* sym = "_+{}|?:\"<>~"; const char* sym = "_+{}|?:\"<>~";
c = sym[code - kMinus]; c = sym[code - kMinus];
} else { } else {
@ -109,17 +103,6 @@ void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) {
c = '\t'; c = '\t';
} else if (code == kBackspace) { } else if (code == kBackspace) {
c = '\b'; c = '\b';
} else if (code == kLShift) {
lshift_ = true;
} else if (code == kRShift) {
rshift_ = true;
}
} else if (action == kReleased) {
if (code == kLShift) {
lshift_ = false;
} else if (code == kRShift) {
rshift_ = false;
}
} }
if (c != '\0') { if (c != '\0') {
@ -127,35 +110,7 @@ void KeyboardListenerBase::HandleKeycode(Keycode code, Action action) {
} }
} }
Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) { Keycode KeyboardListenerBase::ScancodeToKeycode(uint16_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;
}
switch (scancode) { switch (scancode) {
case 0x04: case 0x04:
return kA; return kA;
@ -257,8 +212,10 @@ Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) {
return kBacktick; return kBacktick;
case 0x36: case 0x36:
return kComma; return kComma;
case 0x38: case 0x37:
return kPeriod; return kPeriod;
case 0x38:
return kFSlash;
case 0x39: case 0x39:
return kEsc; // Capslock return kEsc; // Capslock
} }
@ -268,8 +225,4 @@ Keycode KeyboardListenerBase::ScancodeToKeycode(uint8_t scancode) {
return kUnknownKeycode; return kUnknownKeycode;
} }
Action KeyboardListenerBase::ScancodeToAction(uint8_t scancode) {
return (scancode & 0x80) ? kReleased : kPressed;
}
} // namespace mmth } // namespace mmth

View File

@ -78,12 +78,6 @@ enum Keycode {
kRight = 0x5B, kRight = 0x5B,
}; };
enum Action {
kUnknownAction,
kPressed,
kReleased,
};
class KeyboardListenerBase { class KeyboardListenerBase {
public: public:
KeyboardListenerBase(); KeyboardListenerBase();
@ -99,7 +93,7 @@ class KeyboardListenerBase {
// Override this to recieve all raw keycodes. By default // Override this to recieve all raw keycodes. By default
// this function will try to translate each keycode into // this function will try to translate each keycode into
// a printable character and call HandleCharacter. // 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 // This function is called by the default HandleKeycode
// implementation if you do not override it. If it recieves // implementation if you do not override it. If it recieves
@ -109,15 +103,11 @@ class KeyboardListenerBase {
private: private:
PortServer server_; PortServer server_;
bool extended_on_ = false; Keycode ScancodeToKeycode(uint16_t scancode);
bool lshift_ = false; bool IsShift(uint8_t modifiers) {
bool rshift_ = false; return (modifiers & 0x2) || (modifiers & 0x20);
}
Keycode ScancodeToKeycode(uint8_t scancode);
Action ScancodeToAction(uint8_t scancode);
bool IsShift() { return lshift_ || rshift_; }
}; };
} // namespace mmth } // namespace mmth

View File

@ -20,6 +20,11 @@ glcr::ErrorCode PortClient::WriteByte(uint8_t byte) {
ZPortSend(port_cap_, 1, &byte, 0, nullptr)); ZPortSend(port_cap_, 1, &byte, 0, nullptr));
} }
glcr::ErrorCode PortClient::Write(uint16_t data) {
return static_cast<glcr::ErrorCode>(
ZPortSend(port_cap_, 2, &data, 0, nullptr));
}
glcr::ErrorCode PortClient::Write(uint64_t data) { glcr::ErrorCode PortClient::Write(uint64_t data) {
return static_cast<glcr::ErrorCode>( return static_cast<glcr::ErrorCode>(
ZPortSend(port_cap_, 8, &data, 0, nullptr)); ZPortSend(port_cap_, 8, &data, 0, nullptr));

View File

@ -19,6 +19,7 @@ class PortClient {
glcr::ErrorCode WriteString(glcr::String str, z_cap_t cap); glcr::ErrorCode WriteString(glcr::String str, z_cap_t cap);
glcr::ErrorCode WriteByte(uint8_t byte); glcr::ErrorCode WriteByte(uint8_t byte);
glcr::ErrorCode Write(uint16_t data);
glcr::ErrorCode Write(uint64_t data); glcr::ErrorCode Write(uint64_t data);
z_cap_t cap() { return port_cap_; } z_cap_t cap() { return port_cap_; }

View File

@ -55,4 +55,12 @@ glcr::ErrorOr<char> PortServer::RecvChar() {
return byte; return byte;
} }
glcr::ErrorOr<uint16_t> 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 } // namespace mmth

View File

@ -19,6 +19,7 @@ class PortServer {
glcr::ErrorCode PollForIntCap(uint64_t* msg, uint64_t* cap); glcr::ErrorCode PollForIntCap(uint64_t* msg, uint64_t* cap);
glcr::ErrorOr<char> RecvChar(); glcr::ErrorOr<char> RecvChar();
glcr::ErrorOr<uint16_t> RecvUint16();
z_cap_t cap() { return port_cap_; } z_cap_t cap() { return port_cap_; }

View File

@ -42,6 +42,7 @@ void KeyboardDriver::InterruptLoop() {
} }
void KeyboardDriver::ProcessInput(uint64_t input) { void KeyboardDriver::ProcessInput(uint64_t input) {
uint16_t modifiers = (input & 0xFF) << 8;
uint64_t new_bitmap = 0; uint64_t new_bitmap = 0;
for (uint8_t i = 2; i < 8; i++) { for (uint8_t i = 2; i < 8; i++) {
uint8_t code = (input >> (8 * i)) & 0xFF; uint8_t code = (input >> (8 * i)) & 0xFF;
@ -54,15 +55,14 @@ void KeyboardDriver::ProcessInput(uint64_t input) {
uint64_t bit = 1 << code; uint64_t bit = 1 << code;
new_bitmap |= bit; new_bitmap |= bit;
if ((bitmap_ & bit) != bit) { if ((bitmap_ & bit) != bit) {
SendKeypress(code); SendKeypress(modifiers | code);
} }
} }
bitmap_ = new_bitmap; bitmap_ = new_bitmap;
} }
void KeyboardDriver::SendKeypress(uint8_t scancode) { void KeyboardDriver::SendKeypress(uint16_t scancode) {
dbgln("{x}", scancode);
for (mmth::PortClient& client : listeners_) { for (mmth::PortClient& client : listeners_) {
client.WriteByte(scancode); client.Write(scancode);
} }
} }

View File

@ -25,5 +25,5 @@ class KeyboardDriver {
uint64_t bitmap_ = 0; uint64_t bitmap_ = 0;
void ProcessInput(uint64_t input); void ProcessInput(uint64_t input);
void SendKeypress(uint8_t scancode); void SendKeypress(uint16_t scancode);
}; };