From b4051a1ab18790a0b3cc6797b75e69d5b67430c2 Mon Sep 17 00:00:00 2001
From: dingusdev <52434309+dingusdev@users.noreply.github.com>
Date: Fri, 11 Aug 2023 10:34:57 -0700
Subject: [PATCH] ADB keyboard support started
For reasons unknown, no key presses are recognized by the Mac OS.
---
core/hostevents.cpp | 17 ++-
core/hostevents.h | 10 +-
devices/common/adb/adbdevice.cpp | 4 +
devices/common/adb/adbdevice.h | 2 +
devices/common/adb/adbkeyboard.cpp | 235 ++++++++++++++++++++++++++++-
devices/common/adb/adbkeyboard.h | 115 +++++++++++++-
devices/common/viacuda.cpp | 12 +-
devices/common/viacuda.h | 1 +
8 files changed, 374 insertions(+), 22 deletions(-)
diff --git a/core/hostevents.cpp b/core/hostevents.cpp
index 355f6c9..ffb26f7 100644
--- a/core/hostevents.cpp
+++ b/core/hostevents.cpp
@@ -46,12 +46,21 @@ void EventManager::poll_events()
}
break;
- case SDL_KEYDOWN:
- key_downs++;
+ case SDL_KEYDOWN: {
+ KeyboardEvent ke;
+ ke.key_code = event.key.keysym.sym;
+ ke.flags = KEYBOARD_EVENT_DOWN;
+ this->_keyboard_signal.emit(ke);
+ key_downs++;
+ }
break;
- case SDL_KEYUP:
- key_ups++;
+ case SDL_KEYUP: {
+ KeyboardEvent ke;
+ ke.flags = KEYBOARD_EVENT_UP;
+ this->_keyboard_signal.emit(ke);
+ key_ups++;
+ }
break;
case SDL_MOUSEMOTION: {
diff --git a/core/hostevents.h b/core/hostevents.h
index 2092f33..6b1bcc8 100644
--- a/core/hostevents.h
+++ b/core/hostevents.h
@@ -39,7 +39,7 @@ enum : uint32_t {
MOUSE_EVENT_MOTION = 1 << 0,
MOUSE_EVENT_BUTTON = 1 << 1,
KEYBOARD_EVENT_DOWN = 1 << 0,
- KEYBOARD_EVENT_UP = 1 << 1,
+ KEYBOARD_EVENT_UP = 1 << 7,
};
class MouseEvent {
@@ -59,8 +59,12 @@ public:
~KeyboardEvent() = default;
uint32_t flags;
- uint32_t key;
- uint16_t keys_state;
+ uint32_t key_code;
+ uint16_t led_lights;
+ uint8_t key_buffer[16];
+ uint8_t key_state[128];
+ uint8_t adb_code;
+ bool key_pressed;
};
class EventManager {
diff --git a/devices/common/adb/adbdevice.cpp b/devices/common/adb/adbdevice.cpp
index 41cfa3e..cf7e884 100644
--- a/devices/common/adb/adbdevice.cpp
+++ b/devices/common/adb/adbdevice.cpp
@@ -88,6 +88,10 @@ bool AdbDevice::get_register_3() {
return true;
}
+bool AdbDevice::assert_srq() {
+ return this->srq_flag;
+}
+
uint8_t AdbDevice::gen_random_address() {
return (TimerManager::get_instance()->current_time_ns() + 8) & 0xF;
}
diff --git a/devices/common/adb/adbdevice.h b/devices/common/adb/adbdevice.h
index 49f68c1..8824820 100644
--- a/devices/common/adb/adbdevice.h
+++ b/devices/common/adb/adbdevice.h
@@ -65,6 +65,8 @@ protected:
virtual void set_register_2() {};
virtual void set_register_3() {};
+ virtual bool assert_srq();
+
uint8_t exc_event_flag = 0;
uint8_t srq_flag = 0;
uint8_t my_addr = 0;
diff --git a/devices/common/adb/adbkeyboard.cpp b/devices/common/adb/adbkeyboard.cpp
index ce81522..d772b1d 100644
--- a/devices/common/adb/adbkeyboard.cpp
+++ b/devices/common/adb/adbkeyboard.cpp
@@ -32,23 +32,83 @@ AdbKeyboard::AdbKeyboard(std::string name) : AdbDevice(name) {
void AdbKeyboard::event_handler(const KeyboardEvent& event) {
if (event.flags & KEYBOARD_EVENT_DOWN) {
- }
+ adb_code = adb_translate(event.key_code);
+ this->key_pressed = true;
+ for (int input_spot = 0; input_spot < 16; input_spot++) {
+ if (this->key_state[input_spot] == 0xFF) {
+ this->key_state[input_spot] = 0x0 | adb_code;
+ }
+ }
+ }
else if (event.flags & KEYBOARD_EVENT_UP) {
+ this->key_pressed = false;
+ for (int input_spot = 0; input_spot < 16; input_spot++) {
+ this->key_state[input_spot] = 0x80 | adb_code;
+ }
}
}
void AdbKeyboard::reset() {
- this->my_addr = ADB_ADDR_KBD;
- this->dev_handler_id = 2; // Extended ADB keyboard
- this->exc_event_flag = 2;
- this->srq_flag = 1; // enable service requests
+ this->my_addr = ADB_ADDR_KBD;
+ this->dev_handler_id = 2; // Standard ADB keyboard
+ this->exc_event_flag = 1;
+ this->srq_flag = 1; // enable service requests
+ this->flags = 0;
+ this->led_lights = 0;
+ for (int key_array_len = 0; key_array_len < 16; key_array_len++) {
+ this->key_state[key_array_len] = 0xFF;
+ }
+ this->key_pressed = false;
}
bool AdbKeyboard::get_register_0() {
+ if (this->key_pressed) {
+ uint8_t* out_buf = this->host_obj->get_output_buf();
+
+ for (int input_spot = 0; input_spot < 16; input_spot += 2) {
+ out_buf[0] = key_state[input_spot];
+ out_buf[1] = key_state[input_spot + 1];
+
+ this->host_obj->set_output_count(2);
+ }
+ return true;
+ }
+ return false;
+}
+
+bool AdbKeyboard::get_register_2() {
+ if (this->key_pressed) {
+ uint8_t* out_buf = this->host_obj->get_output_buf();
+
+ out_buf[0] = led_lights >> 8;
+ out_buf[1] = led_lights & 0xFF;
+
+ this->host_obj->set_output_count(2);
+ this->key_pressed = false;
+ return true;
+ }
return false;
}
void AdbKeyboard::set_register_2() {
+ for (int input_spot = 0; input_spot < 16; input_spot++) {
+ switch (key_state[input_spot]) {
+ case ADB_keycode_del:
+ led_lights |= 1 << 14;
+ case ADB_keycode_caps:
+ led_lights |= 1 << 13;
+ case ADB_keycode_ctrl:
+ led_lights |= 1 << 11;
+ case ADB_keycode_shift:
+ led_lights |= 1 << 10;
+ case ADB_keycode_opt:
+ led_lights |= 1 << 9;
+ case ADB_keycode_appl:
+ led_lights |= 1 << 8;
+ default:
+ led_lights = 0;
+ }
+ }
}
void AdbKeyboard::set_register_3() {
@@ -78,8 +138,167 @@ void AdbKeyboard::set_register_3() {
}
}
-static const DeviceDescription AdbKeyboard_Descriptor = {
- AdbKeyboard::create, {}, {}
-};
+uint8_t AdbKeyboard::adb_translate(SDL_Keycode input) {
+ // Hoping there's a better way to do this,
+ // but this will have to do for now.
+ switch (input) {
+ case SDLK_0:
+ return ADB_keycode_0;
+ case SDLK_1:
+ return ADB_keycode_1;
+ case SDLK_2:
+ return ADB_keycode_2;
+ case SDLK_3:
+ return ADB_keycode_3;
+ case SDLK_4:
+ return ADB_keycode_4;
+ case SDLK_5:
+ return ADB_keycode_5;
+ case SDLK_6:
+ return ADB_keycode_6;
+ case SDLK_7:
+ return ADB_keycode_7;
+ case SDLK_8:
+ return ADB_keycode_8;
+ case SDLK_9:
+ return ADB_keycode_9;
+ case SDLK_q:
+ return ADB_keycode_q;
+ case SDLK_w:
+ return ADB_keycode_w;
+ case SDLK_e:
+ return ADB_keycode_e;
+ case SDLK_r:
+ return ADB_keycode_r;
+ case SDLK_t:
+ return ADB_keycode_t;
+ case SDLK_y:
+ return ADB_keycode_y;
+ case SDLK_i:
+ return ADB_keycode_i;
+ case SDLK_o:
+ return ADB_keycode_o;
+ case SDLK_u:
+ return ADB_keycode_u;
+ case SDLK_p:
+ return ADB_keycode_p;
+ case SDLK_a:
+ return ADB_keycode_a;
+ case SDLK_s:
+ return ADB_keycode_s;
+ case SDLK_d:
+ return ADB_keycode_d;
+ case SDLK_f:
+ return ADB_keycode_f;
+ case SDLK_g:
+ return ADB_keycode_g;
+ case SDLK_h:
+ return ADB_keycode_h;
+ case SDLK_j:
+ return ADB_keycode_j;
+ case SDLK_k:
+ return ADB_keycode_k;
+ case SDLK_l:
+ return ADB_keycode_l;
+ case SDLK_z:
+ return ADB_keycode_z;
+ case SDLK_x:
+ return ADB_keycode_x;
+ case SDLK_c:
+ return ADB_keycode_c;
+ case SDLK_v:
+ return ADB_keycode_v;
+ case SDLK_b:
+ return ADB_keycode_b;
+ case SDLK_n:
+ return ADB_keycode_n;
+ case SDLK_m:
+ return ADB_keycode_m;
+ case SDLK_SPACE:
+ return ADB_keycode_space;
+ case SDLK_EQUALS:
+ return ADB_keycode_eq;
+ case SDLK_ESCAPE:
+ return ADB_keycode_esc;
+ case SDLK_RETURN:
+ return ADB_keycode_ret;
+ case SDLK_QUOTE:
+ return ADB_keycode_quote;
+ case SDLK_COMMA:
+ return ADB_keycode_comma;
+ case SDLK_PERIOD:
+ return ADB_keycode_per;
+ case SDLK_SLASH:
+ return ADB_keycode_slsh;
+ case SDLK_BACKSLASH:
+ return ADB_keycode_bksl;
+ case SDLK_LEFTBRACKET:
+ return ADB_keycode_lb;
+ case SDLK_RIGHTBRACKET:
+ return ADB_keycode_rb;
+ case SDLK_LEFT:
+ return ADB_keycode_left;
+ case SDLK_RIGHT:
+ return ADB_keycode_right;
+ case SDLK_UP:
+ return ADB_keycode_up;
+ case SDLK_DOWN:
+ return ADB_keycode_down;
+ //case SDLK_BACKQUOTE: -for ref; Apple Extended KB not yet implemented
+ // return ADB_keycode_bkqt;
+ case SDLK_TAB:
+ return ADB_keycode_tab;
+ case SDLK_BACKSPACE:
+ return ADB_keycode_del;
+ case SDLK_LSHIFT:
+ return ADB_keycode_shift;
+ case SDLK_LCTRL:
+ return ADB_keycode_ctrl;
+ case SDLK_LALT:
+ return ADB_keycode_opt;
+ case SDLK_BACKQUOTE:
+ case SDLK_APPLICATION: //temp map
+ case SDLK_MENU:
+ return ADB_keycode_opt;
+ case SDLK_CAPSLOCK:
+ return ADB_keycode_caps;
+ case SDLK_NUMLOCKCLEAR:
+ return ADB_keycode_kp_clr;
+ case SDLK_KP_DIVIDE:
+ return ADB_keycode_kp_div;
+ case SDLK_KP_MULTIPLY:
+ return ADB_keycode_kp_mul;
+ case SDLK_KP_MINUS:
+ return ADB_keycode_kp_minus;
+ case SDLK_KP_PLUS:
+ return ADB_keycode_kp_plus;
+ case SDLK_KP_ENTER:
+ return ADB_keycode_kp_enter;
+ case SDLK_KP_PERIOD:
+ return ADB_keycode_kp_per;
+ case SDLK_KP_0:
+ return ADB_keycode_kp_0;
+ case SDLK_KP_1:
+ return ADB_keycode_kp_1;
+ case SDLK_KP_2:
+ return ADB_keycode_kp_2;
+ case SDLK_KP_3:
+ return ADB_keycode_kp_3;
+ case SDLK_KP_4:
+ return ADB_keycode_kp_4;
+ case SDLK_KP_5:
+ return ADB_keycode_kp_5;
+ case SDLK_KP_6:
+ return ADB_keycode_kp_6;
+ case SDLK_KP_7:
+ return ADB_keycode_kp_7;
+ case SDLK_KP_8:
+ return ADB_keycode_kp_8;
+ case SDLK_KP_9:
+ return ADB_keycode_kp_9;
+ }
+}
+
+static const DeviceDescription AdbKeyboard_Descriptor = {AdbKeyboard::create, {}, {}};
REGISTER_DEVICE(AdbKeyboard, AdbKeyboard_Descriptor);
diff --git a/devices/common/adb/adbkeyboard.h b/devices/common/adb/adbkeyboard.h
index fbebd2b..abfad89 100644
--- a/devices/common/adb/adbkeyboard.h
+++ b/devices/common/adb/adbkeyboard.h
@@ -28,9 +28,108 @@ along with this program. If not, see .
#include
#include
+#include
+
+#include
#include
#include
+enum : uint8_t {
+ ADB_keycode_a,
+ ADB_keycode_s,
+ ADB_keycode_d,
+ ADB_keycode_f,
+ ADB_keycode_h,
+ ADB_keycode_g,
+ ADB_keycode_z,
+ ADB_keycode_x,
+ ADB_keycode_c,
+ ADB_keycode_v,
+ ADB_keycode_int1,
+ ADB_keycode_b,
+ ADB_keycode_q,
+ ADB_keycode_w,
+ ADB_keycode_e,
+ ADB_keycode_r,
+ ADB_keycode_y,
+ ADB_keycode_t,
+ ADB_keycode_1,
+ ADB_keycode_2,
+ ADB_keycode_3,
+ ADB_keycode_4,
+ ADB_keycode_6,
+ ADB_keycode_5,
+ ADB_keycode_eq,
+ ADB_keycode_9,
+ ADB_keycode_7,
+ ADB_keycode_min,
+ ADB_keycode_8,
+ ADB_keycode_0,
+ ADB_keycode_rb,
+ ADB_keycode_o,
+ ADB_keycode_u,
+ ADB_keycode_lb,
+ ADB_keycode_i,
+ ADB_keycode_p,
+ ADB_keycode_ret,
+ ADB_keycode_l,
+ ADB_keycode_j,
+ ADB_keycode_quote,
+ ADB_keycode_k,
+ ADB_keycode_semi,
+ ADB_keycode_bksl,
+ ADB_keycode_comma,
+ ADB_keycode_slsh,
+ ADB_keycode_n,
+ ADB_keycode_m,
+ ADB_keycode_per,
+ ADB_keycode_tab,
+ ADB_keycode_space,
+ ADB_keycode_bkqt,
+ ADB_keycode_del,
+ ADB_keycode_bunk_34,
+ ADB_keycode_esc,
+ ADB_keycode_ctrl,
+ ADB_keycode_appl,
+ ADB_keycode_shift,
+ ADB_keycode_caps,
+ ADB_keycode_opt,
+ ADB_keycode_left,
+ ADB_keycode_right,
+ ADB_keycode_down,
+ ADB_keycode_up,
+ ADB_keycode_bunk_3f,
+ ADB_keycode_bunk_40,
+ ADB_keycode_kp_per,
+ ADB_keycode_bunk_42,
+ ADB_keycode_kp_mul,
+ ADB_keycode_bunk_44,
+ ADB_keycode_kp_plus,
+ ADB_keycode_bunk_46,
+ ADB_keycode_kp_clr,
+ ADB_keycode_bunk_48,
+ ADB_keycode_bunk_49,
+ ADB_keycode_bunk_4a,
+ ADB_keycode_kp_div,
+ ADB_keycode_kp_enter,
+ ADB_keycode_bunk_4d,
+ ADB_keycode_kp_minus,
+ ADB_keycode_bunk_4f,
+ ADB_keycode_bunk_50,
+ ADB_keycode_bunk_51,
+ ADB_keycode_kp_0,
+ ADB_keycode_kp_1,
+ ADB_keycode_kp_2,
+ ADB_keycode_kp_3,
+ ADB_keycode_kp_4,
+ ADB_keycode_kp_5,
+ ADB_keycode_kp_6,
+ ADB_keycode_kp_7,
+ ADB_keycode_bunk_5a,
+ ADB_keycode_kp_8,
+ ADB_keycode_kp_9,
+};
+
class AdbKeyboard : public AdbDevice {
public:
AdbKeyboard(std::string name);
@@ -40,19 +139,25 @@ public:
return std::unique_ptr(new AdbKeyboard("ADB-KEYBOARD"));
}
+ uint8_t adb_translate(SDL_Keycode input);
+
void reset() override;
void event_handler(const KeyboardEvent& event);
bool get_register_0() override;
+ bool get_register_2() override;
void set_register_2() override;
void set_register_3() override;
private:
- int32_t x_rel = 0;
- int32_t y_rel = 0;
- uint8_t buttons_state = 0;
- bool changed = false;
+ uint32_t flags = 0;
+ uint32_t key_code = 0;
+ uint16_t led_lights = 0;
+ uint8_t key_buffer[16] = {0xFF};
+ uint8_t key_state[128] = {0xFF};
+ uint8_t adb_code = 0;
+ bool key_pressed = false;
};
-#endif // ADB_KEYBOARD_H
\ No newline at end of file
+#endif // ADB_KEYBOARD_H
diff --git a/devices/common/viacuda.cpp b/devices/common/viacuda.cpp
index dd804e5..a39c26c 100644
--- a/devices/common/viacuda.cpp
+++ b/devices/common/viacuda.cpp
@@ -479,7 +479,7 @@ void ViaCuda::autopoll_handler() {
return;
// send TALK R0 command to address 3 (mouse)
- uint8_t in_data[2] = { 0x3C, 0};
+ uint8_t in_data[2] = {poll_cmd, 0};
adb_status = this->adb_bus_obj->process_command(in_data, 1);
@@ -490,7 +490,7 @@ void ViaCuda::autopoll_handler() {
// prepare autopoll packet
response_header(CUDA_PKT_ADB, adb_status | ADB_STAT_AUTOPOLL);
- this->out_buf[2] = 0x3C; // put the proper ADB command
+ this->out_buf[2] = poll_cmd; // put the proper ADB command
output_size = this->adb_bus_obj->get_output_count();
if (output_size) {
std::memcpy(&this->out_buf[3], this->adb_bus_obj->get_output_buf(), output_size);
@@ -504,6 +504,14 @@ void ViaCuda::autopoll_handler() {
// draw guest system's attention
schedule_sr_int(USECS_TO_NSECS(30));
}
+
+ //alternate between mouse and keyboard between cycles
+ if (poll_cmd == 0x3C) {
+ poll_cmd = 0x2C;
+ }
+ else if (poll_cmd == 0x2C) {
+ poll_cmd = 0x3C;
+ }
}
void ViaCuda::pseudo_command(int cmd, int data_count) {
diff --git a/devices/common/viacuda.h b/devices/common/viacuda.h
index 1422690..30ae984 100644
--- a/devices/common/viacuda.h
+++ b/devices/common/viacuda.h
@@ -206,6 +206,7 @@ private:
uint8_t old_byteack;
uint8_t treq;
uint8_t in_buf[CUDA_IN_BUF_SIZE];
+ uint8_t poll_cmd = 0x3C;
int32_t in_count;
uint8_t out_buf[16];
int32_t out_count;