[Mammoth/Voyageurs] Add shift modifiers for scancodes.
This commit is contained in:
parent
a9351b222d
commit
844f55c7d0
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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_; }
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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_; }
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue