Add support for USB HID keyboard over AOAv2
This provides a better input experience, by simulating a physical keyboard. It converts SDL keyboard events to proper HID events, and send them over AOAv2. This is a rewriting and bugfix of the origin code from @amosbird: <https://github.com/Genymobile/scrcpy/issues/279#issuecomment-453819354> The feature is enabled the command line option -K or --hid-keyboard, and is only available on Linux, over USB. Refs <https://source.android.com/devices/accessories/aoa2#hid-support> Refs <https://www.usb.org/sites/default/files/hid1_11.pdf> PR #2632 <https://github.com/Genymobile/scrcpy/pull/2632> Signed-off-by: Romain Vimont <rom@rom1v.com>
This commit is contained in:
committed by
Romain Vimont
parent
f7d1efdf1d
commit
207082977a
42
app/src/hid_keyboard.h
Normal file
42
app/src/hid_keyboard.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef SC_HID_KEYBOARD_H
|
||||
#define SC_HID_KEYBOARD_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "aoa_hid.h"
|
||||
#include "trait/key_processor.h"
|
||||
|
||||
// See "SDL2/SDL_scancode.h".
|
||||
// Maybe SDL_Keycode is used by most people, but SDL_Scancode is taken from USB
|
||||
// HID protocol.
|
||||
// 0x65 is Application, typically AT-101 Keyboard ends here.
|
||||
#define SC_HID_KEYBOARD_KEYS 0x66
|
||||
|
||||
/**
|
||||
* HID keyboard events are sequence-based, every time keyboard state changes
|
||||
* it sends an array of currently pressed keys, the host is responsible for
|
||||
* compare events and determine which key becomes pressed and which key becomes
|
||||
* released. In order to convert SDL_KeyboardEvent to HID events, we first use
|
||||
* an array of keys to save each keys' state. And when a SDL_KeyboardEvent was
|
||||
* emitted, we updated our state, and then we use a loop to generate HID
|
||||
* events. The sequence of array elements is unimportant and when too much keys
|
||||
* pressed at the same time (more than report count), we should generate
|
||||
* phantom state. Don't forget that modifiers should be updated too, even for
|
||||
* phantom state.
|
||||
*/
|
||||
struct sc_hid_keyboard {
|
||||
struct sc_key_processor key_processor; // key processor trait
|
||||
|
||||
struct sc_aoa *aoa;
|
||||
bool keys[SC_HID_KEYBOARD_KEYS];
|
||||
};
|
||||
|
||||
bool
|
||||
sc_hid_keyboard_init(struct sc_hid_keyboard *kb, struct sc_aoa *aoa);
|
||||
|
||||
void
|
||||
sc_hid_keyboard_destroy(struct sc_hid_keyboard *kb);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user