wip
This commit is contained in:
@@ -33,6 +33,9 @@
|
|||||||
#define HID_KEYBOARD_RESERVED 0x00
|
#define HID_KEYBOARD_RESERVED 0x00
|
||||||
#define HID_KEYBOARD_ERROR_ROLL_OVER 0x01
|
#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.
|
* For HID over AOAv2, only report descriptor is needed.
|
||||||
*
|
*
|
||||||
@@ -170,6 +173,43 @@ sdl_keymod_to_hid_modifiers(SDL_Keymod mod) {
|
|||||||
return modifiers;
|
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
|
static bool
|
||||||
convert_hid_keyboard_event(struct hid_keyboard *kb, struct hid_event *hid_event,
|
convert_hid_keyboard_event(struct hid_keyboard *kb, struct hid_event *hid_event,
|
||||||
const SDL_KeyboardEvent *event) {
|
const SDL_KeyboardEvent *event) {
|
||||||
@@ -276,9 +316,11 @@ sc_key_processor_process_text(struct sc_key_processor *kp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
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;
|
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,
|
bool ok = aoa_setup_hid(aoa, HID_KEYBOARD_ACCESSORY_ID,
|
||||||
keyboard_report_desc,
|
keyboard_report_desc,
|
||||||
ARRAY_LEN(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;
|
kb->key_processor.ops = &ops;
|
||||||
|
|
||||||
|
// FIXME to avoid pipe error
|
||||||
|
usleep(100000);
|
||||||
|
send_mod_lock_state(kb, lock_mod);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,10 @@
|
|||||||
// 0x65 is Application, typically AT-101 Keyboard ends here.
|
// 0x65 is Application, typically AT-101 Keyboard ends here.
|
||||||
#define HID_KEYBOARD_KEYS 0x66
|
#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
|
* HID keyboard events are sequence-based, every time keyboard state changes
|
||||||
* it sends an array of currently pressed keys, the host is responsible for
|
* it sends an array of currently pressed keys, the host is responsible for
|
||||||
@@ -36,7 +40,7 @@ struct hid_keyboard {
|
|||||||
};
|
};
|
||||||
|
|
||||||
bool
|
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
|
void
|
||||||
hid_keyboard_destroy(struct hid_keyboard *kb);
|
hid_keyboard_destroy(struct hid_keyboard *kb);
|
||||||
|
|||||||
@@ -376,6 +376,8 @@ input_manager_process_key(struct input_manager *im,
|
|||||||
|
|
||||||
bool smod = is_shortcut_mod(im, mod);
|
bool smod = is_shortcut_mod(im, mod);
|
||||||
|
|
||||||
|
LOGD("=== %x", (int) mod);
|
||||||
|
|
||||||
if (down && !repeat) {
|
if (down && !repeat) {
|
||||||
if (keycode == im->last_keycode && mod == im->last_mod) {
|
if (keycode == im->last_keycode && mod == im->last_mod) {
|
||||||
++im->key_repeat;
|
++im->key_repeat;
|
||||||
|
|||||||
@@ -254,6 +254,18 @@ stream_on_eos(struct stream *stream, void *userdata) {
|
|||||||
SDL_PushEvent(&stop_event);
|
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
|
bool
|
||||||
scrcpy(struct scrcpy_options *options) {
|
scrcpy(struct scrcpy_options *options) {
|
||||||
static struct scrcpy scrcpy;
|
static struct scrcpy scrcpy;
|
||||||
@@ -462,7 +474,9 @@ scrcpy(struct scrcpy_options *options) {
|
|||||||
goto aoa_hid_end;
|
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_join(&s->aoa);
|
||||||
aoa_stop(&s->aoa);
|
aoa_stop(&s->aoa);
|
||||||
aoa_destroy(&s->aoa);
|
aoa_destroy(&s->aoa);
|
||||||
|
|||||||
Reference in New Issue
Block a user