Expose named input modes (wip)

Replace:
 - -K/--hid-keyboard by --keyboard-input-mode
 - -M/--hid-mouse by --mouse-input-mode

Each supports 3 possible values (for now):
 - disable
 - inject
 - aoa

Signed-off-by: Romain Vimont <rom@rom1v.com>
uhid.1
Simon Chan 6 months ago committed by Romain Vimont
parent 2ad93d1fc0
commit 24efeace4b

@ -27,8 +27,8 @@ _scrcpy() {
--force-adb-forward
--forward-all-clicks
-h --help
--keyboard-input-mode=
--kill-adb-on-close
-K --hid-keyboard
--legacy-paste
--list-camera-sizes
--list-cameras
@ -115,6 +115,10 @@ _scrcpy() {
COMPREPLY=($(compgen -W 'front back external' -- "$cur"))
return
;;
--keyboard-input-mode)
COMPREPLY=($(compgen -W 'inject aoa' -- "$cur"))
return
;;
--orientation|--display-orientation)
COMPREPLY=($(compgen -W '0 90 180 270 flip0 flip90 flip180 flip270' -- "$cur"))
return

@ -34,8 +34,8 @@ arguments=(
'--force-adb-forward[Do not attempt to use \"adb reverse\" to connect to the device]'
'--forward-all-clicks[Forward clicks to device]'
{-h,--help}'[Print the help]'
'--keyboard-input-mode=[Set the keyboard input mode]:mode:(inject aoa)'
'--kill-adb-on-close[Kill adb when scrcpy terminates]'
{-K,--hid-keyboard}'[Simulate a physical keyboard by using HID over AOAv2]'
'--legacy-paste[Inject computer clipboard text as a sequence of key events on Ctrl+v]'
'--list-camera-sizes[List the valid camera capture sizes]'
'--list-cameras[List cameras available on the device]'

@ -93,6 +93,8 @@ enum {
OPT_DISPLAY_ORIENTATION,
OPT_RECORD_ORIENTATION,
OPT_ORIENTATION,
OPT_KEYBOARD_INPUT_MODE,
OPT_MOUSE_INPUT_MODE,
};
struct sc_option {
@ -359,14 +361,19 @@ static const struct sc_option options[] = {
.text = "Print this help.",
},
{
.longopt_id = OPT_KILL_ADB_ON_CLOSE,
.longopt = "kill-adb-on-close",
.text = "Kill adb when scrcpy terminates.",
},
{
.shortopt = 'K',
.longopt = "hid-keyboard",
.text = "Simulate a physical keyboard by using HID over AOAv2.\n"
.longopt_id = OPT_KEYBOARD_INPUT_MODE,
.longopt = "keyboard-input-mode",
.argdesc = "value",
.text = "Select how to send keyboard inputs to the device.\n"
"Possible values are \"disable\", \"inject\" and \"aoa\".\n"
"\n"
"\"disable\" does not send keyboard inputs to the device.\n"
"\n"
"\"inject\" uses the Android system API to deliver keyboard\n"
"events to applications.\n"
"\n"
"\"aoa\" simulates a physical keyboard using the AOAv2\n"
"protocol. It may only work over USB.\n"
"It provides a better experience for IME users, and allows to "
"generate non-ASCII characters, contrary to the default "
"injection method.\n"
@ -378,7 +385,19 @@ static const struct sc_option options[] = {
"android.settings.HARD_KEYBOARD_SETTINGS`.\n"
"However, the option is only available when the HID keyboard "
"is enabled (or a physical keyboard is connected).\n"
"Also see --hid-mouse.",
"Also see --mouse-input-mode and --otg."
"\n"
"Default is \"inject\" (or \"aoa\" if --otg is set).",
},
{
.longopt_id = OPT_KILL_ADB_ON_CLOSE,
.longopt = "kill-adb-on-close",
.text = "Kill adb when scrcpy terminates.",
},
{
// deprecated
.shortopt = 'K',
.longopt = "hid-keyboard",
},
{
.longopt_id = OPT_LEGACY_PASTE,
@ -440,7 +459,7 @@ static const struct sc_option options[] = {
"LAlt, LSuper or RSuper toggle the capture mode, to give "
"control of the mouse back to the computer.\n"
"It may only work over USB.\n"
"Also see --hid-keyboard.",
"Also see --keyboard-input-mode and --otg.",
},
{
.longopt_id = OPT_MAX_FPS,
@ -449,6 +468,26 @@ static const struct sc_option options[] = {
.text = "Limit the frame rate of screen capture (officially supported "
"since Android 10, but may work on earlier versions).",
},
{
.longopt_id = OPT_MOUSE_INPUT_MODE,
.longopt = "mouse-input-mode",
.argdesc = "value",
.text = "Select how to send mouse inputs to the device.\n"
"Possible values are \"disable\", \"inject\" and \"aoa\".\n"
"\n"
"\"disable\" does not send mouse inputs to the device.\n"
"\n"
"\"inject\" uses the Android system API to deliver mouse\n"
"events to applications.\n"
"\n"
"\"aoa\" simulates a physical mouse using the AOAv2\n"
"protocol. It may only work over USB.\n"
"In this mode, the computer mouse is captured to control the "
"device directly (relative mouse mode).\n"
"LAlt, LSuper or RSuper toggle the capture mode, to give "
"control of the mouse back to the computer.\n"
"Also see --keyboard-input-mode and --otg.",
},
{
.shortopt = 'n',
.longopt = "no-control",
@ -543,10 +582,11 @@ static const struct sc_option options[] = {
"mirroring is disabled.\n"
"LAlt, LSuper or RSuper toggle the mouse capture mode, to give "
"control of the mouse back to the computer.\n"
"If any of --hid-keyboard or --hid-mouse is set, only enable "
"keyboard or mouse respectively, otherwise enable both.\n"
"Keyboard and mouse may be disabled separately using\n"
"--keyboard-input-mode=disable and\n"
"--mouse-input-mode=disable.\n"
"It may only work over USB.\n"
"See --hid-keyboard and --hid-mouse.",
"See --keyboard-input-mode and --mouse-input-mode.",
},
{
.shortopt = 'p',
@ -1902,6 +1942,61 @@ parse_camera_fps(const char *s, uint16_t *camera_fps) {
return true;
}
static bool
parse_keyboard_input_mode(const char *optarg,
enum sc_keyboard_input_mode *mode) {
if (!strcmp(optarg, "disable")) {
*mode = SC_KEYBOARD_INPUT_MODE_DISABLED;
return true;
}
if (!strcmp(optarg, "inject")) {
*mode = SC_KEYBOARD_INPUT_MODE_INJECT;
return true;
}
if (!strcmp(optarg, "aoa")) {
#ifdef HAVE_USB
*mode = SC_KEYBOARD_INPUT_MODE_AOA;
return true;
#else
LOGE("--keyboard-input-mode=aoa is disabled.");
return false;
#endif
}
LOGE("Unsupported keyboard input mode: %s (expected disable, inject, aoa)",
optarg);
return false;
}
static bool
parse_mouse_input_mode(const char *optarg, enum sc_mouse_input_mode *mode) {
if (!strcmp(optarg, "disable")) {
*mode = SC_MOUSE_INPUT_MODE_DISABLED;
return true;
}
if (!strcmp(optarg, "inject")) {
*mode = SC_MOUSE_INPUT_MODE_INJECT;
return true;
}
if (!strcmp(optarg, "aoa")) {
#ifdef HAVE_USB
*mode = SC_MOUSE_INPUT_MODE_AOA;
return true;
#else
LOGE("--mouse-input-mode=aoa is disabled.");
return false;
#endif
}
LOGE("Unsupported mouse input mode: %s (expected disable, inject, aoa)",
optarg);
return false;
}
static bool
parse_time_limit(const char *s, sc_tick *tick) {
long value;
@ -1991,12 +2086,20 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
break;
case 'K':
#ifdef HAVE_USB
opts->keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_HID;
LOGW("-K/--hid-keyboard is deprecated, use "
"--keyboard-input-mode=aoa instead.");
opts->keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_AOA;
break;
#else
LOGE("HID over AOA (-K/--hid-keyboard) is disabled.");
return false;
#endif
case OPT_KEYBOARD_INPUT_MODE:
if (!parse_keyboard_input_mode(optarg,
&opts->keyboard_input_mode)) {
return false;
}
break;
case OPT_MAX_FPS:
if (!parse_max_fps(optarg, &opts->max_fps)) {
return false;
@ -2009,12 +2112,19 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
break;
case 'M':
#ifdef HAVE_USB
opts->mouse_input_mode = SC_MOUSE_INPUT_MODE_HID;
LOGW("-M/--hid-mouse is deprecated, use --mouse-input-mode=aoa "
"instead.");
opts->mouse_input_mode = SC_MOUSE_INPUT_MODE_AOA;
break;
#else
LOGE("HID over AOA (-M/--hid-mouse) is disabled.");
return false;
#endif
case OPT_MOUSE_INPUT_MODE:
if (!parse_mouse_input_mode(optarg, &opts->mouse_input_mode)) {
return false;
}
break;
case OPT_LOCK_VIDEO_ORIENTATION:
if (!parse_lock_video_orientation(optarg,
&opts->lock_video_orientation)) {
@ -2461,6 +2571,15 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
}
#endif
if (opts->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_AUTO) {
opts->keyboard_input_mode = otg ? SC_KEYBOARD_INPUT_MODE_AOA
: SC_KEYBOARD_INPUT_MODE_INJECT;
}
if (opts->mouse_input_mode == SC_MOUSE_INPUT_MODE_AUTO) {
opts->mouse_input_mode = otg ? SC_MOUSE_INPUT_MODE_AOA
: SC_MOUSE_INPUT_MODE_INJECT;
}
if ((opts->tunnel_host || opts->tunnel_port) && !opts->force_adb_forward) {
LOGI("Tunnel host/port is set, "
"--force-adb-forward automatically enabled.");
@ -2621,12 +2740,12 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[],
}
# ifdef _WIN32
if (!otg && (opts->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID
|| opts->mouse_input_mode == SC_MOUSE_INPUT_MODE_HID)) {
if (!otg && (opts->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_AOA
|| opts->mouse_input_mode == SC_MOUSE_INPUT_MODE_AOA)) {
LOGE("On Windows, it is not possible to open a USB device already open "
"by another process (like adb).");
LOGE("Therefore, -K/--hid-keyboard and -M/--hid-mouse may only work in "
"OTG mode (--otg).");
LOGE("Therefore, --keyboard-input-mode=aoa and --mouse-input-mode=aoa "
"may only work in OTG mode (--otg).");
return false;
}
# endif

@ -21,8 +21,8 @@ const struct scrcpy_options scrcpy_options_default = {
.video_source = SC_VIDEO_SOURCE_DISPLAY,
.audio_source = SC_AUDIO_SOURCE_AUTO,
.record_format = SC_RECORD_FORMAT_AUTO,
.keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_INJECT,
.mouse_input_mode = SC_MOUSE_INPUT_MODE_INJECT,
.keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_AUTO,
.mouse_input_mode = SC_MOUSE_INPUT_MODE_AUTO,
.camera_facing = SC_CAMERA_FACING_ANY,
.port_range = {
.first = DEFAULT_LOCAL_PORT_RANGE_FIRST,

@ -140,13 +140,17 @@ enum sc_lock_video_orientation {
};
enum sc_keyboard_input_mode {
SC_KEYBOARD_INPUT_MODE_AUTO,
SC_KEYBOARD_INPUT_MODE_DISABLED,
SC_KEYBOARD_INPUT_MODE_INJECT,
SC_KEYBOARD_INPUT_MODE_HID,
SC_KEYBOARD_INPUT_MODE_AOA,
};
enum sc_mouse_input_mode {
SC_MOUSE_INPUT_MODE_AUTO,
SC_MOUSE_INPUT_MODE_DISABLED,
SC_MOUSE_INPUT_MODE_INJECT,
SC_MOUSE_INPUT_MODE_HID,
SC_MOUSE_INPUT_MODE_AOA,
};
enum sc_key_inject_mode {

@ -543,11 +543,11 @@ scrcpy(struct scrcpy_options *options) {
if (options->control) {
#ifdef HAVE_USB
bool use_hid_keyboard =
options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID;
bool use_hid_mouse =
options->mouse_input_mode == SC_MOUSE_INPUT_MODE_HID;
if (use_hid_keyboard || use_hid_mouse) {
bool use_aoa_keyboard =
options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_AOA;
bool use_aoa_mouse =
options->mouse_input_mode == SC_MOUSE_INPUT_MODE_AOA;
if (use_aoa_keyboard || use_aoa_mouse) {
bool ok = sc_acksync_init(&s->acksync);
if (!ok) {
goto end;
@ -590,7 +590,7 @@ scrcpy(struct scrcpy_options *options) {
goto aoa_hid_end;
}
if (use_hid_keyboard) {
if (use_aoa_keyboard) {
if (sc_hid_keyboard_init(&s->keyboard_hid, &s->aoa)) {
hid_keyboard_initialized = true;
kp = &s->keyboard_hid.key_processor;
@ -599,7 +599,7 @@ scrcpy(struct scrcpy_options *options) {
}
}
if (use_hid_mouse) {
if (use_aoa_mouse) {
if (sc_hid_mouse_init(&s->mouse_hid, &s->aoa)) {
hid_mouse_initialized = true;
mp = &s->mouse_hid.mouse_processor;
@ -636,19 +636,19 @@ aoa_hid_end:
if (use_hid_keyboard && !hid_keyboard_initialized) {
LOGE("Fallback to default keyboard injection method "
"(-K/--hid-keyboard ignored)");
"(--keyboard-input-mode=aoa ignored)");
options->keyboard_input_mode = SC_KEYBOARD_INPUT_MODE_INJECT;
}
if (use_hid_mouse && !hid_mouse_initialized) {
LOGE("Fallback to default mouse injection method "
"(-M/--hid-mouse ignored)");
"(--mouse-input-mode=aoa ignored)");
options->mouse_input_mode = SC_MOUSE_INPUT_MODE_INJECT;
}
}
#else
assert(options->keyboard_input_mode != SC_KEYBOARD_INPUT_MODE_HID);
assert(options->mouse_input_mode != SC_MOUSE_INPUT_MODE_HID);
assert(options->keyboard_input_mode != SC_KEYBOARD_INPUT_MODE_AOA);
assert(options->mouse_input_mode != SC_MOUSE_INPUT_MODE_AOA);
#endif
// keyboard_input_mode may have been reset if HID mode failed

@ -53,6 +53,25 @@ scrcpy_otg(struct scrcpy_options *options) {
static struct scrcpy_otg scrcpy_otg;
struct scrcpy_otg *s = &scrcpy_otg;
bool enable_keyboard;
assert(options->keyboard_input_mode != SC_KEYBOARD_INPUT_MODE_AUTO);
switch (options->keyboard_input_mode) {
case SC_KEYBOARD_INPUT_MODE_AOA:
enable_keyboard = true;
break;
case SC_KEYBOARD_INPUT_MODE_DISABLED:
enable_keyboard = false;
break;
default:
LOGE("In --otg mode, --keyboard-input-mode must be either aoa or "
"disable");
goto end;
}
if (options->keyboard_input_mode != SC_KEYBOARD_INPUT_MODE_AOA
&& options->keyboard_input_mode != SC_KEYBOARD_INPUT_MODE_DISABLED) {
return SCRCPY_EXIT_FAILURE;
}
const char *serial = options->serial;
if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) {
@ -118,9 +137,9 @@ scrcpy_otg(struct scrcpy_options *options) {
aoa_initialized = true;
bool enable_keyboard =
options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID;
options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_AOA;
bool enable_mouse =
options->mouse_input_mode == SC_MOUSE_INPUT_MODE_HID;
options->mouse_input_mode == SC_MOUSE_INPUT_MODE_AOA;
// If neither --hid-keyboard or --hid-mouse is passed, enable both
if (!enable_keyboard && !enable_mouse) {

Loading…
Cancel
Save