ADB keyboard support started

For reasons unknown, no key presses are recognized by the Mac OS.
This commit is contained in:
dingusdev 2023-08-11 10:34:57 -07:00
parent d2e7c9a5df
commit b4051a1ab1
8 changed files with 374 additions and 22 deletions

View File

@ -46,12 +46,21 @@ void EventManager::poll_events()
}
break;
case SDL_KEYDOWN:
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:
case SDL_KEYUP: {
KeyboardEvent ke;
ke.flags = KEYBOARD_EVENT_UP;
this->_keyboard_signal.emit(ke);
key_ups++;
}
break;
case SDL_MOUSEMOTION: {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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;

View File

@ -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->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);

View File

@ -28,9 +28,108 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
#include <devices/common/adb/adbdevice.h>
#include <devices/common/hwcomponent.h>
#include <SDL.h>
#include <cinttypes>
#include <memory>
#include <string>
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<AdbKeyboard>(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

View File

@ -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) {

View File

@ -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;