Synchronize HID keyboard state on first event

When an AOA HID keyboard is registered, CAPSLOCK and NUMLOCK are both
disabled, regardless of the state of the computer keyboard.

To synchronize the state, on first key event, inject CAPSLOCK and/or
NUMLOCK if necessary.
This commit is contained in:
Romain Vimont 2021-10-21 20:44:19 +02:00
parent ad1f3fd90f
commit 82f73fca50
2 changed files with 49 additions and 0 deletions

View file

@ -240,6 +240,44 @@ convert_hid_keyboard_event(struct hid_keyboard *kb, struct hid_event *hid_event,
return true;
}
static bool
push_mod_lock_state(struct hid_keyboard *kb, uint16_t sdl_mod) {
bool capslock = sdl_mod & KMOD_CAPS;
bool numlock = sdl_mod & KMOD_NUM;
if (!capslock && !numlock) {
// Nothing to do
return true;
}
struct hid_event hid_event;
if (!hid_keyboard_event_init(&hid_event)) {
LOGW("Could not initialize HID event");
return false;
}
#define SC_SCANCODE_CAPSLOCK SDL_SCANCODE_CAPSLOCK
#define SC_SCANCODE_NUMLOCK SDL_SCANCODE_NUMLOCKCLEAR
unsigned i = 0;
if (capslock) {
hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_CAPSLOCK;
++i;
}
if (numlock) {
hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_NUMLOCK;
++i;
}
if (!aoa_push_hid_event(kb->aoa, &hid_event)) {
LOGW("Could request HID event");
return false;
}
LOGD("HID keyboard state synchronized");
return true;
}
static void
sc_key_processor_process_key(struct sc_key_processor *kp,
const SDL_KeyboardEvent *event) {
@ -254,6 +292,13 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
struct hid_event hid_event;
// Not all keys are supported, just ignore unsupported keys
if (convert_hid_keyboard_event(kb, &hid_event, event)) {
if (!kb->mod_lock_synchronized) {
// Inject CAPSLOCK and/or NUMLOCK if necessary to synchronize
// keyboard state
if (push_mod_lock_state(kb, event->keysym.mod)) {
kb->mod_lock_synchronized = true;
}
}
if (!aoa_push_hid_event(kb->aoa, &hid_event)) {
hid_event_destroy(&hid_event);
LOGW("Could request HID event");
@ -285,6 +330,8 @@ hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa) {
// Reset all states
memset(kb->keys, false, HID_KEYBOARD_KEYS);
kb->mod_lock_synchronized = false;
static const struct sc_key_processor_ops ops = {
.process_key = sc_key_processor_process_key,
.process_text = sc_key_processor_process_text,

View file

@ -33,6 +33,8 @@ struct hid_keyboard {
struct aoa *aoa;
bool keys[HID_KEYBOARD_KEYS];
bool mod_lock_synchronized;
};
bool