mirror of
https://github.com/dingusdev/dingusppc.git
synced 2024-09-27 04:54:42 +00:00
Fix keyboard events occasionally being dropped
AdbKeyboard would copy the event into its own fields and set the changed field, so that we could return the event when register was 0. However, if a subsequent event was received before ADB polling, the previous event would be overwritten and lost. Fix this by maintaining a queue of events, so that we can return everything since the last poll.
This commit is contained in:
parent
d37d83c5b6
commit
d08b486db0
@ -34,14 +34,7 @@ AdbKeyboard::AdbKeyboard(std::string name) : AdbDevice(name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AdbKeyboard::event_handler(const KeyboardEvent& event) {
|
void AdbKeyboard::event_handler(const KeyboardEvent& event) {
|
||||||
this->key = event.key;
|
this->pending_events.push_back(std::make_unique<KeyboardEvent>(event));
|
||||||
if (event.flags & KEYBOARD_EVENT_DOWN) {
|
|
||||||
this->key_state = 0;
|
|
||||||
}
|
|
||||||
else if (event.flags & KEYBOARD_EVENT_UP) {
|
|
||||||
this->key_state = 1;
|
|
||||||
}
|
|
||||||
this->changed = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdbKeyboard::reset() {
|
void AdbKeyboard::reset() {
|
||||||
@ -49,32 +42,42 @@ void AdbKeyboard::reset() {
|
|||||||
this->dev_handler_id = 2; // Extended ADB keyboard
|
this->dev_handler_id = 2; // Extended ADB keyboard
|
||||||
this->exc_event_flag = 1;
|
this->exc_event_flag = 1;
|
||||||
this->srq_flag = 1; // enable service requests
|
this->srq_flag = 1; // enable service requests
|
||||||
this->key = 0;
|
this->pending_events.clear();
|
||||||
this->key_state = 0;
|
|
||||||
this->changed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AdbKeyboard::get_register_0() {
|
bool AdbKeyboard::get_register_0() {
|
||||||
if (this->changed) {
|
if (this->pending_events.empty()) {
|
||||||
uint8_t* out_buf = this->host_obj->get_output_buf();
|
return false;
|
||||||
|
}
|
||||||
|
uint8_t* out_buf = this->host_obj->get_output_buf();
|
||||||
|
out_buf[0] = this->consume_pending_event();
|
||||||
|
out_buf[1] = this->consume_pending_event();
|
||||||
|
this->host_obj->set_output_count(2);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
out_buf[0] = (this->key_state << 7) | (this->key & 0x7F);
|
uint8_t AdbKeyboard::consume_pending_event() {
|
||||||
// It's possible that we get two events before the host polls us, but
|
if (this->pending_events.empty()) {
|
||||||
// in practice it has not come up. We need to set the key status bit to
|
// In most cases we have only on pending event when the host polls us,
|
||||||
// 1 (released), and the key to a non-existent one (0x7F). Otherwise if
|
// but we need to fill two entries of the output buffer. We need to set
|
||||||
// we leave it empty, the host will think that the 'a' key (code 0) is
|
// the key status bit to 1 (released), and the key to a non-existent
|
||||||
// pressed.
|
// one (0x7F). Otherwise if we leave it empty, the host will think that
|
||||||
out_buf[1] = 0xFF;
|
// the 'a' key (code 0) is pressed (status 0).
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
std::unique_ptr<KeyboardEvent> event = std::move(this->pending_events.front());
|
||||||
|
this->pending_events.pop_front();
|
||||||
|
|
||||||
this->key = 0;
|
uint8_t key_state = 0;
|
||||||
this->key_state = 0;
|
if (event->flags & KEYBOARD_EVENT_DOWN) {
|
||||||
this->changed = false;
|
key_state = 0;
|
||||||
|
} else if (event->flags & KEYBOARD_EVENT_UP) {
|
||||||
this->host_obj->set_output_count(2);
|
key_state = 1;
|
||||||
return true;
|
} else {
|
||||||
|
LOG_F(WARNING, "%s: unknown keyboard event flags %x", this->name.c_str(), event->flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return (key_state << 7) | (event->key & 0x7F);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AdbKeyboard::set_register_2() {
|
void AdbKeyboard::set_register_2() {
|
||||||
|
@ -27,6 +27,7 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|||||||
#include <devices/common/adb/adbdevice.h>
|
#include <devices/common/adb/adbdevice.h>
|
||||||
#include <devices/common/hwcomponent.h>
|
#include <devices/common/hwcomponent.h>
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@ -50,9 +51,9 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t key = 0;
|
std::deque<std::unique_ptr<KeyboardEvent>> pending_events;
|
||||||
uint8_t key_state = 0;
|
|
||||||
bool changed = false;
|
uint8_t consume_pending_event();
|
||||||
};
|
};
|
||||||
|
|
||||||
// ADB Extended Keyboard raw key codes (most of which eventually became virtual
|
// ADB Extended Keyboard raw key codes (most of which eventually became virtual
|
||||||
|
Loading…
Reference in New Issue
Block a user