mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2025-12-12 09:10:30 +08:00
add keyboard interface (#95)
This commit is contained in:
parent
793edf8203
commit
38fae01cc0
@ -25,18 +25,21 @@
|
|||||||
|
|
||||||
namespace DRIVERS {
|
namespace DRIVERS {
|
||||||
|
|
||||||
enum type {
|
enum type {
|
||||||
USB_MOUSE_ABSOLUTE,
|
DUMMY = 0,
|
||||||
USB_MOUSE_RELATIVE,
|
USB_MOUSE_ABSOLUTE,
|
||||||
USB_MOUSE_ABSOLUTE_WIN98,
|
USB_MOUSE_RELATIVE,
|
||||||
};
|
USB_MOUSE_ABSOLUTE_WIN98,
|
||||||
|
USB_KEYBOARD,
|
||||||
|
PS2_KEYBOARD,
|
||||||
|
};
|
||||||
|
|
||||||
class Driver {
|
class Driver {
|
||||||
public:
|
public:
|
||||||
Driver(type _type) : _type(_type) {}
|
Driver(type _type) : _type(_type) {}
|
||||||
uint8_t getType() { return _type; }
|
uint8_t getType() { return _type; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
type _type;
|
type _type;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,9 +26,41 @@
|
|||||||
|
|
||||||
namespace DRIVERS {
|
namespace DRIVERS {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool caps;
|
bool caps;
|
||||||
bool scroll;
|
bool scroll;
|
||||||
bool num;
|
bool num;
|
||||||
} KeyboardLedsState;
|
} KeyboardLedsState;
|
||||||
|
|
||||||
|
|
||||||
|
struct Keyboard : public Driver {
|
||||||
|
using Driver::Driver;
|
||||||
|
|
||||||
|
virtual void begin() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Release all keys
|
||||||
|
*/
|
||||||
|
virtual void clear() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends key
|
||||||
|
* @param code ???
|
||||||
|
* @param state true pressed, false released
|
||||||
|
*/
|
||||||
|
virtual void sendKey(uint8_t code, bool state) {}
|
||||||
|
|
||||||
|
virtual void periodic() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* False if online or unknown. Otherwise true.
|
||||||
|
*/
|
||||||
|
virtual bool isOffline() { return false; }
|
||||||
|
|
||||||
|
virtual KeyboardLedsState getLeds() {
|
||||||
|
KeyboardLedsState result = {};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
namespace DRIVERS {
|
namespace DRIVERS {
|
||||||
|
|
||||||
class Mouse : public Driver {
|
class Mouse : public Driver {
|
||||||
using Driver::Driver;
|
using Driver::Driver;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,11 +49,10 @@
|
|||||||
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
static UsbKeyboard *_usb_kbd = NULL;
|
|
||||||
static UsbMouseAbsolute *_usb_mouse_abs = NULL;
|
static UsbMouseAbsolute *_usb_mouse_abs = NULL;
|
||||||
static UsbMouseRelative *_usb_mouse_rel = NULL;
|
static UsbMouseRelative *_usb_mouse_rel = NULL;
|
||||||
|
|
||||||
static Ps2Keyboard *_ps2_kbd = NULL;
|
static DRIVERS::Keyboard *_kbd = nullptr;
|
||||||
|
|
||||||
#ifdef HID_DYNAMIC
|
#ifdef HID_DYNAMIC
|
||||||
static bool _reset_required = false;
|
static bool _reset_required = false;
|
||||||
@ -114,11 +113,12 @@ static void _initOutputs() {
|
|||||||
uint8_t kbd = outputs & PROTO::OUTPUTS1::KEYBOARD::MASK;
|
uint8_t kbd = outputs & PROTO::OUTPUTS1::KEYBOARD::MASK;
|
||||||
switch (kbd) {
|
switch (kbd) {
|
||||||
# ifdef HID_WITH_USB
|
# ifdef HID_WITH_USB
|
||||||
case PROTO::OUTPUTS1::KEYBOARD::USB: _usb_kbd = new UsbKeyboard(); break;
|
case PROTO::OUTPUTS1::KEYBOARD::USB: _kbd = new UsbKeyboard(); break;
|
||||||
# endif
|
# endif
|
||||||
# ifdef HID_WITH_PS2
|
# ifdef HID_WITH_PS2
|
||||||
case PROTO::OUTPUTS1::KEYBOARD::PS2: _ps2_kbd = new Ps2Keyboard(); break;
|
case PROTO::OUTPUTS1::KEYBOARD::PS2: _kbd = new Ps2Keyboard(); break;
|
||||||
# endif
|
# endif
|
||||||
|
default: _kbd = new DRIVERS::Keyboard(DRIVERS::DUMMY); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mouse = outputs & PROTO::OUTPUTS1::MOUSE::MASK;
|
uint8_t mouse = outputs & PROTO::OUTPUTS1::MOUSE::MASK;
|
||||||
@ -136,14 +136,7 @@ static void _initOutputs() {
|
|||||||
|
|
||||||
USBDevice.attach();
|
USBDevice.attach();
|
||||||
|
|
||||||
switch (kbd) {
|
_kbd->begin();
|
||||||
# ifdef HID_WITH_USB
|
|
||||||
case PROTO::OUTPUTS1::KEYBOARD::USB: _usb_kbd->begin(); break;
|
|
||||||
# endif
|
|
||||||
# ifdef HID_WITH_PS2
|
|
||||||
case PROTO::OUTPUTS1::KEYBOARD::PS2: _ps2_kbd->begin(); break;
|
|
||||||
# endif
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (mouse) {
|
switch (mouse) {
|
||||||
# ifdef HID_WITH_USB
|
# ifdef HID_WITH_USB
|
||||||
@ -181,9 +174,7 @@ static void _cmdSetConnected(const uint8_t *data) { // 1 byte
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _cmdClearHid(const uint8_t *_) { // 0 bytes
|
static void _cmdClearHid(const uint8_t *_) { // 0 bytes
|
||||||
if (_usb_kbd) {
|
_kbd->clear();
|
||||||
_usb_kbd->clear();
|
|
||||||
}
|
|
||||||
if (_usb_mouse_abs) {
|
if (_usb_mouse_abs) {
|
||||||
_usb_mouse_abs->clear();
|
_usb_mouse_abs->clear();
|
||||||
} else if (_usb_mouse_rel) {
|
} else if (_usb_mouse_rel) {
|
||||||
@ -192,11 +183,7 @@ static void _cmdClearHid(const uint8_t *_) { // 0 bytes
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _cmdKeyEvent(const uint8_t *data) { // 2 bytes
|
static void _cmdKeyEvent(const uint8_t *data) { // 2 bytes
|
||||||
if (_usb_kbd) {
|
_kbd->sendKey(data[0], data[1]);
|
||||||
_usb_kbd->sendKey(data[0], data[1]);
|
|
||||||
} else if (_ps2_kbd) {
|
|
||||||
_ps2_kbd->sendKey(data[0], data[1]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _cmdMouseButtonEvent(const uint8_t *data) { // 2 bytes
|
static void _cmdMouseButtonEvent(const uint8_t *data) { // 2 bytes
|
||||||
@ -287,20 +274,21 @@ static void _sendResponse(uint8_t code) {
|
|||||||
}
|
}
|
||||||
response[2] = PROTO::OUTPUTS1::DYNAMIC;
|
response[2] = PROTO::OUTPUTS1::DYNAMIC;
|
||||||
# endif
|
# endif
|
||||||
if (_usb_kbd) {
|
if (DRIVERS::DUMMY != _kbd->getType()) {
|
||||||
response[1] |= (_usb_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
|
response[1] |= (_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
|
||||||
KeyboardLedsState leds = _usb_kbd->getLeds();
|
KeyboardLedsState leds = _kbd->getLeds();
|
||||||
response[1] |= (leds.caps ? PROTO::PONG::CAPS : 0);
|
response[1] |= (leds.caps ? PROTO::PONG::CAPS : 0);
|
||||||
response[1] |= (leds.num ? PROTO::PONG::NUM : 0);
|
response[1] |= (leds.num ? PROTO::PONG::NUM : 0);
|
||||||
response[1] |= (leds.scroll ? PROTO::PONG::SCROLL : 0);
|
response[1] |= (leds.scroll ? PROTO::PONG::SCROLL : 0);
|
||||||
response[2] |= PROTO::OUTPUTS1::KEYBOARD::USB;
|
switch (_kbd->getType())
|
||||||
} else if (_ps2_kbd) {
|
{
|
||||||
response[1] |= (_ps2_kbd->isOffline() ? PROTO::PONG::KEYBOARD_OFFLINE : 0);
|
case DRIVERS::USB_KEYBOARD:
|
||||||
KeyboardLedsState leds = _usb_kbd->getLeds();
|
response[2] |= PROTO::OUTPUTS1::KEYBOARD::USB;
|
||||||
response[1] |= (leds.caps ? PROTO::PONG::CAPS : 0);
|
break;
|
||||||
response[1] |= (leds.num ? PROTO::PONG::NUM : 0);
|
case DRIVERS::PS2_KEYBOARD:
|
||||||
response[1] |= (leds.scroll ? PROTO::PONG::SCROLL : 0);
|
response[2] |= PROTO::OUTPUTS1::KEYBOARD::PS2;
|
||||||
response[2] |= PROTO::OUTPUTS1::KEYBOARD::PS2;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_usb_mouse_abs) {
|
if (_usb_mouse_abs) {
|
||||||
response[1] |= _usb_mouse_abs->isOffline() ? PROTO::PONG::MOUSE_OFFLINE : 0;
|
response[1] |= _usb_mouse_abs->isOffline() ? PROTO::PONG::MOUSE_OFFLINE : 0;
|
||||||
@ -363,16 +351,7 @@ int main() {
|
|||||||
aumProxyUsbVbus();
|
aumProxyUsbVbus();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef HID_WITH_USB
|
_kbd->periodic();
|
||||||
if (_usb_kbd) {
|
|
||||||
_usb_kbd->periodic();
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
# ifdef HID_WITH_PS2
|
|
||||||
if (_ps2_kbd) {
|
|
||||||
_ps2_kbd->periodic();
|
|
||||||
}
|
|
||||||
# endif
|
|
||||||
|
|
||||||
# ifdef CMD_SERIAL
|
# ifdef CMD_SERIAL
|
||||||
if (CMD_SERIAL.available() > 0) {
|
if (CMD_SERIAL.available() > 0) {
|
||||||
|
|||||||
@ -32,21 +32,21 @@
|
|||||||
// #define HID_PS2_KBD_DATA_PIN 5
|
// #define HID_PS2_KBD_DATA_PIN 5
|
||||||
|
|
||||||
|
|
||||||
class Ps2Keyboard {
|
class Ps2Keyboard : public DRIVERS::Keyboard {
|
||||||
// https://wiki.osdev.org/PS/2_Keyboard
|
// https://wiki.osdev.org/PS/2_Keyboard
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Ps2Keyboard() : _dev(HID_PS2_KBD_CLOCK_PIN, HID_PS2_KBD_DATA_PIN) {}
|
Ps2Keyboard() : DRIVERS::Keyboard(DRIVERS::PS2_KEYBOARD), _dev(HID_PS2_KBD_CLOCK_PIN, HID_PS2_KBD_DATA_PIN) {}
|
||||||
|
|
||||||
void begin() {
|
void begin() override {
|
||||||
_dev.keyboard_init();
|
_dev.keyboard_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void periodic() {
|
void periodic() override {
|
||||||
_dev.keyboard_handle(&_leds);
|
_dev.keyboard_handle(&_leds);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendKey(uint8_t code, bool state) {
|
void sendKey(uint8_t code, bool state) override {
|
||||||
Ps2KeyType ps2_type;
|
Ps2KeyType ps2_type;
|
||||||
uint8_t ps2_code;
|
uint8_t ps2_code;
|
||||||
|
|
||||||
@ -75,11 +75,11 @@ class Ps2Keyboard {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isOffline() {
|
bool isOffline() override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardLedsState getLeds() {
|
KeyboardLedsState getLeds() override {
|
||||||
periodic();
|
periodic();
|
||||||
KeyboardLedsState result = {
|
KeyboardLedsState result = {
|
||||||
.caps = _leds & 0b00000100,
|
.caps = _leds & 0b00000100,
|
||||||
|
|||||||
@ -69,15 +69,15 @@ using namespace DRIVERS;
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class UsbKeyboard {
|
class UsbKeyboard : public DRIVERS::Keyboard {
|
||||||
public:
|
public:
|
||||||
UsbKeyboard() {}
|
UsbKeyboard() : DRIVERS::Keyboard(DRIVERS::USB_KEYBOARD) {}
|
||||||
|
|
||||||
void begin() {
|
void begin() override {
|
||||||
_kbd.begin();
|
_kbd.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void periodic() {
|
void periodic() override {
|
||||||
# ifdef HID_USB_CHECK_ENDPOINT
|
# ifdef HID_USB_CHECK_ENDPOINT
|
||||||
static unsigned long prev_ts = 0;
|
static unsigned long prev_ts = 0;
|
||||||
if (is_micros_timed_out(prev_ts, 50000)) {
|
if (is_micros_timed_out(prev_ts, 50000)) {
|
||||||
@ -92,11 +92,11 @@ class UsbKeyboard {
|
|||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() override {
|
||||||
_kbd.releaseAll();
|
_kbd.releaseAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sendKey(uint8_t code, bool state) {
|
void sendKey(uint8_t code, bool state) override {
|
||||||
KeyboardKeycode usb_code = keymapUsb(code);
|
KeyboardKeycode usb_code = keymapUsb(code);
|
||||||
if (usb_code != KEY_ERROR_UNDEFINED) {
|
if (usb_code != KEY_ERROR_UNDEFINED) {
|
||||||
if (state ? _kbd.add(usb_code) : _kbd.remove(usb_code)) {
|
if (state ? _kbd.add(usb_code) : _kbd.remove(usb_code)) {
|
||||||
@ -107,7 +107,7 @@ class UsbKeyboard {
|
|||||||
|
|
||||||
CLS_IS_OFFLINE(_kbd)
|
CLS_IS_OFFLINE(_kbd)
|
||||||
|
|
||||||
KeyboardLedsState getLeds() {
|
KeyboardLedsState getLeds() override {
|
||||||
uint8_t leds = _kbd.getLeds();
|
uint8_t leds = _kbd.getLeds();
|
||||||
KeyboardLedsState result = {
|
KeyboardLedsState result = {
|
||||||
.caps = leds & LED_CAPS_LOCK,
|
.caps = leds & LED_CAPS_LOCK,
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user