Make HID keyboard and mouse optional in OTG mode

Allow to only enable HID keyboard or HID mouse:

    scrcpy --otg -K   # keyboard only
    scrcpy --otg -M   # mouse only
    scrcpy --otg -KM  # keyboard and mouse
    scrcpy --otg      # keyboard and mouse

PR #2974 <https://github.com/Genymobile/scrcpy/pull/2974>
This commit is contained in:
Romain Vimont 2022-01-26 22:50:10 +01:00
parent c5be0d6438
commit ea68a003a2
5 changed files with 88 additions and 46 deletions

View file

@ -866,6 +866,16 @@ scrcpy --otg
scrcpy --otg -s 0123456789abcdef
```
It is possible to enable only HID keyboard or HID mouse:
```bash
scrcpy --otg --hid-keyboard # keyboard only
scrcpy --otg --hid-mouse # mouse only
scrcpy --otg --hid-keyboard --hid-mouse # keyboard and mouse
# for convenience, enable both by default
scrcpy --otg # keyboard and mouse
```
Like `--hid-keyboard` and `--hid-mouse`, it only works if the device is
connected by USB, and is currently only supported on Linux.

View file

@ -170,6 +170,8 @@ In this mode, adb (USB debugging) is not necessary, and mirroring is disabled.
LAlt, LSuper or RSuper toggle the mouse capture mode, to give control of the mouse back to the computer.
If any of \fB\-\-hid\-keyboard\fR or \fB\-\-hid\-mouse\fR is set, only enable keyboard or mouse respectively, otherwise enable both.
It may only work over USB, and is currently only supported on Linux.
See \fB\-\-hid\-keyboard\fR and \fB\-\-hid\-mouse\fR.

View file

@ -287,6 +287,8 @@ 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."
"It may only work over USB, and is currently only supported "
"on Linux.\n"
"See --hid-keyboard and --hid-mouse.",

View file

@ -134,17 +134,32 @@ scrcpy_otg(struct scrcpy_options *options) {
}
aoa_initialized = true;
ok = sc_hid_keyboard_init(&s->keyboard, &s->aoa);
if (!ok) {
goto end;
}
keyboard = &s->keyboard;
bool enable_keyboard =
options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID;
bool enable_mouse =
options->mouse_input_mode == SC_MOUSE_INPUT_MODE_HID;
ok = sc_hid_mouse_init(&s->mouse, &s->aoa);
if (!ok) {
goto end;
// If neither --hid-keyboard or --hid-mouse is passed, enable both
if (!enable_keyboard && !enable_mouse) {
enable_keyboard = true;
enable_mouse = true;
}
if (enable_keyboard) {
ok = sc_hid_keyboard_init(&s->keyboard, &s->aoa);
if (!ok) {
goto end;
}
keyboard = &s->keyboard;
}
if (enable_mouse) {
ok = sc_hid_mouse_init(&s->mouse, &s->aoa);
if (!ok) {
goto end;
}
mouse = &s->mouse;
}
mouse = &s->mouse;
ok = sc_aoa_start(&s->aoa);
if (!ok) {

View file

@ -6,6 +6,7 @@
static void
sc_screen_otg_capture_mouse(struct sc_screen_otg *screen, bool capture) {
assert(screen->mouse);
if (SDL_SetRelativeMouseMode(capture)) {
LOGE("Could not set relative mouse mode to %s: %s",
capture ? "true" : "false", SDL_GetError());
@ -78,8 +79,10 @@ sc_screen_otg_init(struct sc_screen_otg *screen,
LOGW("Could not load icon");
}
// Capture mouse on start
sc_screen_otg_capture_mouse(screen, true);
if (screen->mouse) {
// Capture mouse on start
sc_screen_otg_capture_mouse(screen, true);
}
return true;
@ -189,64 +192,74 @@ sc_screen_otg_handle_event(struct sc_screen_otg *screen, SDL_Event *event) {
sc_screen_otg_render(screen);
break;
case SDL_WINDOWEVENT_FOCUS_LOST:
sc_screen_otg_capture_mouse(screen, false);
if (screen->mouse) {
sc_screen_otg_capture_mouse(screen, false);
}
break;
}
return;
case SDL_KEYDOWN: {
SDL_Keycode key = event->key.keysym.sym;
if (sc_screen_otg_is_mouse_capture_key(key)) {
if (!screen->mouse_capture_key_pressed) {
screen->mouse_capture_key_pressed = key;
} else {
// Another mouse capture key has been pressed, cancel mouse
// (un)capture
screen->mouse_capture_key_pressed = 0;
case SDL_KEYDOWN:
if (screen->mouse) {
SDL_Keycode key = event->key.keysym.sym;
if (sc_screen_otg_is_mouse_capture_key(key)) {
if (!screen->mouse_capture_key_pressed) {
screen->mouse_capture_key_pressed = key;
} else {
// Another mouse capture key has been pressed, cancel
// mouse (un)capture
screen->mouse_capture_key_pressed = 0;
}
// Mouse capture keys are never forwarded to the device
return;
}
// Mouse capture keys are never forwarded to the device
return;
}
sc_screen_otg_process_key(screen, &event->key);
if (screen->keyboard) {
sc_screen_otg_process_key(screen, &event->key);
}
break;
}
case SDL_KEYUP: {
SDL_Keycode key = event->key.keysym.sym;
SDL_Keycode cap = screen->mouse_capture_key_pressed;
screen->mouse_capture_key_pressed = 0;
if (sc_screen_otg_is_mouse_capture_key(key)) {
if (key == cap) {
// A mouse capture key has been pressed then released:
// toggle the capture mouse mode
sc_screen_otg_capture_mouse(screen,
!screen->mouse_captured);
case SDL_KEYUP:
if (screen->mouse) {
SDL_Keycode key = event->key.keysym.sym;
SDL_Keycode cap = screen->mouse_capture_key_pressed;
screen->mouse_capture_key_pressed = 0;
if (sc_screen_otg_is_mouse_capture_key(key)) {
if (key == cap) {
// A mouse capture key has been pressed then released:
// toggle the capture mouse mode
sc_screen_otg_capture_mouse(screen,
!screen->mouse_captured);
}
// Mouse capture keys are never forwarded to the device
return;
}
// Mouse capture keys are never forwarded to the device
return;
}
sc_screen_otg_process_key(screen, &event->key);
if (screen->keyboard) {
sc_screen_otg_process_key(screen, &event->key);
}
break;
}
case SDL_MOUSEMOTION:
if (screen->mouse_captured) {
if (screen->mouse && screen->mouse_captured) {
sc_screen_otg_process_mouse_motion(screen, &event->motion);
}
break;
case SDL_MOUSEBUTTONDOWN:
if (screen->mouse_captured) {
if (screen->mouse && screen->mouse_captured) {
sc_screen_otg_process_mouse_button(screen, &event->button);
}
break;
case SDL_MOUSEBUTTONUP:
if (screen->mouse_captured) {
sc_screen_otg_process_mouse_button(screen, &event->button);
} else {
sc_screen_otg_capture_mouse(screen, true);
if (screen->mouse) {
if (screen->mouse_captured) {
sc_screen_otg_process_mouse_button(screen, &event->button);
} else {
sc_screen_otg_capture_mouse(screen, true);
}
}
break;
case SDL_MOUSEWHEEL:
if (screen->mouse_captured) {
if (screen->mouse && screen->mouse_captured) {
sc_screen_otg_process_mouse_wheel(screen, &event->wheel);
}
break;