From f595d16cde7c7cc6749df4d913666e51375534fd Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Wed, 20 Oct 2021 22:04:11 +0200 Subject: [PATCH] wip --- app/src/hid_keyboard.c | 48 ++++++++++++++++++++++++++++++++++++++++- app/src/hid_keyboard.h | 6 +++++- app/src/input_manager.c | 2 ++ app/src/scrcpy.c | 16 +++++++++++++- 4 files changed, 69 insertions(+), 3 deletions(-) diff --git a/app/src/hid_keyboard.c b/app/src/hid_keyboard.c index b66676b1..9bc1ee87 100644 --- a/app/src/hid_keyboard.c +++ b/app/src/hid_keyboard.c @@ -33,6 +33,9 @@ #define HID_KEYBOARD_RESERVED 0x00 #define HID_KEYBOARD_ERROR_ROLL_OVER 0x01 +#define SC_SCANCODE_CAPSLOCK 57 +#define SC_SCANCODE_NUMLOCK 83 + /** * For HID over AOAv2, only report descriptor is needed. * @@ -170,6 +173,43 @@ sdl_keymod_to_hid_modifiers(SDL_Keymod mod) { return modifiers; } +static bool +send_mod_lock_state(struct hid_keyboard *kb, unsigned lock_mod) { + assert(!(lock_mod & ~SC_MOD_MASK)); + if (!lock_mod) { + // Nothing to do + return true; + } + + struct hid_event hid_event; + hid_event.from_accessory_id = HID_KEYBOARD_ACCESSORY_ID; + hid_event.buffer = create_hid_keyboard_event(); + if (!hid_event.buffer) { + return false; + } + hid_event.size = HID_KEYBOARD_EVENT_SIZE; + + unsigned i = 0; + if (lock_mod & SC_MOD_CAPSLOCK) { + hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_CAPSLOCK; + ++i; + } + if (lock_mod & SC_MOD_NUMLOCK) { + hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_NUMLOCK; + ++i; + } + +// for (int i = 0; i < HID_KEYBOARD_EVENT_SIZE; ++i) +// printf("%02x ", hid_event->buffer[i]); +// printf("\n"); + + if (!aoa_push_hid_event(kb->aoa, &hid_event)) { + LOGW("Could request HID event"); + } + + return true; +} + static bool convert_hid_keyboard_event(struct hid_keyboard *kb, struct hid_event *hid_event, const SDL_KeyboardEvent *event) { @@ -276,9 +316,11 @@ sc_key_processor_process_text(struct sc_key_processor *kp, } bool -hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa) { +hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa, unsigned lock_mod) { kb->aoa = aoa; + // FIXME In practice, sending CAPS_LOCK immediately after fails with a Pipe + // error but we must know immediately if this fails or not bool ok = aoa_setup_hid(aoa, HID_KEYBOARD_ACCESSORY_ID, keyboard_report_desc, ARRAY_LEN(keyboard_report_desc)); @@ -297,6 +339,10 @@ hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa) { kb->key_processor.ops = &ops; + // FIXME to avoid pipe error + usleep(100000); + send_mod_lock_state(kb, lock_mod); + return true; } diff --git a/app/src/hid_keyboard.h b/app/src/hid_keyboard.h index b57070aa..606ee3c3 100644 --- a/app/src/hid_keyboard.h +++ b/app/src/hid_keyboard.h @@ -16,6 +16,10 @@ // 0x65 is Application, typically AT-101 Keyboard ends here. #define HID_KEYBOARD_KEYS 0x66 +#define SC_MOD_MASK 0x3 +#define SC_MOD_CAPSLOCK 0x1 +#define SC_MOD_NUMLOCK 0x2 + /** * HID keyboard events are sequence-based, every time keyboard state changes * it sends an array of currently pressed keys, the host is responsible for @@ -36,7 +40,7 @@ struct hid_keyboard { }; bool -hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa); +hid_keyboard_init(struct hid_keyboard *kb, struct aoa *aoa, unsigned lock_mod); void hid_keyboard_destroy(struct hid_keyboard *kb); diff --git a/app/src/input_manager.c b/app/src/input_manager.c index bba3c998..e82ae67a 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -376,6 +376,8 @@ input_manager_process_key(struct input_manager *im, bool smod = is_shortcut_mod(im, mod); + LOGD("=== %x", (int) mod); + if (down && !repeat) { if (keycode == im->last_keycode && mod == im->last_mod) { ++im->key_repeat; diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 2a51b111..1d7d982a 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -254,6 +254,18 @@ stream_on_eos(struct stream *stream, void *userdata) { SDL_PushEvent(&stop_event); } +static unsigned +to_sc_mod(SDL_Keymod sdl_mod) { + unsigned mod = 0; + if (sdl_mod & KMOD_CAPS) { + mod |= SC_MOD_CAPSLOCK; + } + if (sdl_mod & KMOD_NUM) { + mod |= SC_MOD_NUMLOCK; + } + return mod; +} + bool scrcpy(struct scrcpy_options *options) { static struct scrcpy scrcpy; @@ -462,7 +474,9 @@ scrcpy(struct scrcpy_options *options) { goto aoa_hid_end; } - if (!hid_keyboard_init(&s->keyboard_hid, &s->aoa)) { + // FIXME: SDL_GetModState() always returns 0 here :/ + unsigned mod = to_sc_mod(SDL_GetModState()); + if (!hid_keyboard_init(&s->keyboard_hid, &s->aoa, mod)) { aoa_join(&s->aoa); aoa_stop(&s->aoa); aoa_destroy(&s->aoa);