Add UHID mouse support
Use the following command: scrcpy --mouse=uhid
This commit is contained in:
parent
6c18c50fcf
commit
2c106e8ce3
@ -121,7 +121,7 @@ _scrcpy() {
|
|||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--mouse)
|
--mouse)
|
||||||
COMPREPLY=($(compgen -W 'disabled sdk aoa' -- "$cur"))
|
COMPREPLY=($(compgen -W 'disabled sdk aoa uhid' -- "$cur"))
|
||||||
return
|
return
|
||||||
;;
|
;;
|
||||||
--orientation|--display-orientation)
|
--orientation|--display-orientation)
|
||||||
|
@ -45,7 +45,7 @@ arguments=(
|
|||||||
{-m,--max-size=}'[Limit both the width and height of the video to value]'
|
{-m,--max-size=}'[Limit both the width and height of the video to value]'
|
||||||
{-M,--hid-mouse}'[Simulate a physical mouse by using HID over AOAv2]'
|
{-M,--hid-mouse}'[Simulate a physical mouse by using HID over AOAv2]'
|
||||||
'--max-fps=[Limit the frame rate of screen capture]'
|
'--max-fps=[Limit the frame rate of screen capture]'
|
||||||
'--mouse[Set the mouse input mode]:mode:(disabled sdk aoa)'
|
'--mouse[Set the mouse input mode]:mode:(disabled sdk aoa uhid)'
|
||||||
{-n,--no-control}'[Disable device control \(mirror the device in read only\)]'
|
{-n,--no-control}'[Disable device control \(mirror the device in read only\)]'
|
||||||
{-N,--no-playback}'[Disable video and audio playback]'
|
{-N,--no-playback}'[Disable video and audio playback]'
|
||||||
'--no-audio[Disable audio forwarding]'
|
'--no-audio[Disable audio forwarding]'
|
||||||
|
@ -36,6 +36,7 @@ src = [
|
|||||||
'src/trait/frame_source.c',
|
'src/trait/frame_source.c',
|
||||||
'src/trait/packet_source.c',
|
'src/trait/packet_source.c',
|
||||||
'src/uhid/keyboard_uhid.c',
|
'src/uhid/keyboard_uhid.c',
|
||||||
|
'src/uhid/mouse_uhid.c',
|
||||||
'src/uhid/uhid_output.c',
|
'src/uhid/uhid_output.c',
|
||||||
'src/util/acksync.c',
|
'src/util/acksync.c',
|
||||||
'src/util/audiobuf.c',
|
'src/util/audiobuf.c',
|
||||||
|
@ -247,8 +247,9 @@ Possible values are "disabled", "sdk" and "aoa":
|
|||||||
- "disabled" does not send mouse inputs to the device.
|
- "disabled" does not send mouse inputs to the device.
|
||||||
- "sdk" uses the Android system API to deliver mouse events to applications.
|
- "sdk" uses the Android system API to deliver mouse events to applications.
|
||||||
- "aoa" simulates a physical mouse using the AOAv2 protocol. It may only work over USB.
|
- "aoa" simulates a physical mouse using the AOAv2 protocol. It may only work over USB.
|
||||||
|
- "uhid" simulates a physical HID mouse using the Linux HID kernel module on the device.
|
||||||
|
|
||||||
In "aoa" mode, the computer mouse is captured to control the device directly (relative mouse mode).
|
In "aoa" and "uhid" modes, the computer mouse is captured to control the device directly (relative mouse mode).
|
||||||
|
|
||||||
LAlt, LSuper or RSuper toggle the capture mode, to give control of the mouse back to the computer.
|
LAlt, LSuper or RSuper toggle the capture mode, to give control of the mouse back to the computer.
|
||||||
|
|
||||||
|
@ -468,8 +468,10 @@ static const struct sc_option options[] = {
|
|||||||
"events to applications.\n"
|
"events to applications.\n"
|
||||||
"\"aoa\" simulates a physical mouse using the AOAv2 protocol\n"
|
"\"aoa\" simulates a physical mouse using the AOAv2 protocol\n"
|
||||||
"It may only work over USB.\n"
|
"It may only work over USB.\n"
|
||||||
"In \"aoa\" mode, the computer mouse is captured to control "
|
"\"uhid\" simulates a physical HID mouse using the Linux UHID "
|
||||||
"the device directly (relative mouse mode).\n"
|
"kernel module on the device."
|
||||||
|
"In \"aoa\" and \"uhid\" modes, the computer mouse is captured "
|
||||||
|
"to control the device directly (relative mouse mode).\n"
|
||||||
"LAlt, LSuper or RSuper toggle the capture mode, to give "
|
"LAlt, LSuper or RSuper toggle the capture mode, to give "
|
||||||
"control of the mouse back to the computer.\n"
|
"control of the mouse back to the computer.\n"
|
||||||
"Also see --keyboard.",
|
"Also see --keyboard.",
|
||||||
@ -1989,7 +1991,12 @@ parse_mouse(const char *optarg, enum sc_mouse_input_mode *mode) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
LOGE("Unsupported mouse: %s (expected disabled, sdk or aoa)", optarg);
|
if (!strcmp(optarg, "uhid")) {
|
||||||
|
*mode = SC_MOUSE_INPUT_MODE_UHID;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
LOGE("Unsupported mouse: %s (expected disabled, sdk, aoa or uhid)", optarg);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +152,7 @@ enum sc_mouse_input_mode {
|
|||||||
SC_MOUSE_INPUT_MODE_DISABLED,
|
SC_MOUSE_INPUT_MODE_DISABLED,
|
||||||
SC_MOUSE_INPUT_MODE_SDK,
|
SC_MOUSE_INPUT_MODE_SDK,
|
||||||
SC_MOUSE_INPUT_MODE_AOA,
|
SC_MOUSE_INPUT_MODE_AOA,
|
||||||
|
SC_MOUSE_INPUT_MODE_UHID,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum sc_key_inject_mode {
|
enum sc_key_inject_mode {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "server.h"
|
#include "server.h"
|
||||||
#include "uhid/keyboard_uhid.h"
|
#include "uhid/keyboard_uhid.h"
|
||||||
|
#include "uhid/mouse_uhid.h"
|
||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
# include "usb/aoa_hid.h"
|
# include "usb/aoa_hid.h"
|
||||||
# include "usb/keyboard_aoa.h"
|
# include "usb/keyboard_aoa.h"
|
||||||
@ -76,6 +77,7 @@ struct scrcpy {
|
|||||||
#ifdef HAVE_USB
|
#ifdef HAVE_USB
|
||||||
struct sc_mouse_aoa mouse_aoa;
|
struct sc_mouse_aoa mouse_aoa;
|
||||||
#endif
|
#endif
|
||||||
|
struct sc_mouse_uhid mouse_uhid;
|
||||||
};
|
};
|
||||||
struct sc_timeout timeout;
|
struct sc_timeout timeout;
|
||||||
};
|
};
|
||||||
@ -681,6 +683,12 @@ aoa_hid_end:
|
|||||||
if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_SDK) {
|
if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_SDK) {
|
||||||
sc_mouse_sdk_init(&s->mouse_sdk, &s->controller);
|
sc_mouse_sdk_init(&s->mouse_sdk, &s->controller);
|
||||||
mp = &s->mouse_sdk.mouse_processor;
|
mp = &s->mouse_sdk.mouse_processor;
|
||||||
|
} else if (options->mouse_input_mode == SC_MOUSE_INPUT_MODE_UHID) {
|
||||||
|
bool ok = sc_mouse_uhid_init(&s->mouse_uhid, &s->controller);
|
||||||
|
if (!ok) {
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
mp = &s->mouse_uhid.mouse_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_controller_configure(&s->controller, acksync, uhid_devices);
|
sc_controller_configure(&s->controller, acksync, uhid_devices);
|
||||||
|
89
app/src/uhid/mouse_uhid.c
Normal file
89
app/src/uhid/mouse_uhid.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
#include "mouse_uhid.h"
|
||||||
|
|
||||||
|
#include "hid/hid_mouse.h"
|
||||||
|
#include "input_events.h"
|
||||||
|
#include "util/log.h"
|
||||||
|
|
||||||
|
/** Downcast mouse processor to mouse_uhid */
|
||||||
|
#define DOWNCAST(MP) container_of(MP, struct sc_mouse_uhid, mouse_processor)
|
||||||
|
|
||||||
|
#define UHID_MOUSE_ID 2
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_mouse_uhid_send_input(struct sc_mouse_uhid *kb,
|
||||||
|
const struct sc_hid_event *event, const char *name) {
|
||||||
|
struct sc_control_msg msg;
|
||||||
|
msg.type = SC_CONTROL_MSG_TYPE_UHID_INPUT;
|
||||||
|
msg.uhid_input.id = UHID_MOUSE_ID;
|
||||||
|
|
||||||
|
assert(event->size <= SC_HID_MAX_SIZE);
|
||||||
|
memcpy(msg.uhid_input.data, event->data, event->size);
|
||||||
|
msg.uhid_input.size = event->size;
|
||||||
|
|
||||||
|
if (!sc_controller_push_msg(kb->controller, &msg)) {
|
||||||
|
LOGE("Could not send UHID_INPUT message (%s)", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
|
||||||
|
const struct sc_mouse_motion_event *event) {
|
||||||
|
struct sc_mouse_uhid *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
|
struct sc_hid_event hid_event;
|
||||||
|
sc_hid_mouse_event_from_motion(&hid_event, event);
|
||||||
|
|
||||||
|
sc_mouse_uhid_send_input(mouse, &hid_event, "mouse motion");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
|
||||||
|
const struct sc_mouse_click_event *event) {
|
||||||
|
struct sc_mouse_uhid *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
|
struct sc_hid_event hid_event;
|
||||||
|
sc_hid_mouse_event_from_click(&hid_event, event);
|
||||||
|
|
||||||
|
sc_mouse_uhid_send_input(mouse, &hid_event, "mouse click");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
||||||
|
const struct sc_mouse_scroll_event *event) {
|
||||||
|
struct sc_mouse_uhid *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
|
struct sc_hid_event hid_event;
|
||||||
|
sc_hid_mouse_event_from_scroll(&hid_event, event);
|
||||||
|
|
||||||
|
sc_mouse_uhid_send_input(mouse, &hid_event, "mouse scroll");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
|
||||||
|
struct sc_controller *controller) {
|
||||||
|
mouse->controller = controller;
|
||||||
|
|
||||||
|
static const struct sc_mouse_processor_ops ops = {
|
||||||
|
.process_mouse_motion = sc_mouse_processor_process_mouse_motion,
|
||||||
|
.process_mouse_click = sc_mouse_processor_process_mouse_click,
|
||||||
|
.process_mouse_scroll = sc_mouse_processor_process_mouse_scroll,
|
||||||
|
// Touch events not supported (coordinates are not relative)
|
||||||
|
.process_touch = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
mouse->mouse_processor.ops = &ops;
|
||||||
|
|
||||||
|
mouse->mouse_processor.relative_mode = true;
|
||||||
|
|
||||||
|
struct sc_control_msg msg;
|
||||||
|
msg.type = SC_CONTROL_MSG_TYPE_UHID_CREATE;
|
||||||
|
msg.uhid_create.id = UHID_MOUSE_ID;
|
||||||
|
msg.uhid_create.report_desc = SC_HID_MOUSE_REPORT_DESC;
|
||||||
|
msg.uhid_create.report_desc_size = SC_HID_MOUSE_REPORT_DESC_LEN;
|
||||||
|
if (!sc_controller_push_msg(controller, &msg)) {
|
||||||
|
LOGE("Could not send UHID_CREATE message (mouse)");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
19
app/src/uhid/mouse_uhid.h
Normal file
19
app/src/uhid/mouse_uhid.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef SC_MOUSE_UHID_H
|
||||||
|
#define SC_MOUSE_UHID_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "controller.h"
|
||||||
|
#include "trait/mouse_processor.h"
|
||||||
|
|
||||||
|
struct sc_mouse_uhid {
|
||||||
|
struct sc_mouse_processor mouse_processor; // mouse processor trait
|
||||||
|
|
||||||
|
struct sc_controller *controller;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool
|
||||||
|
sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
|
||||||
|
struct sc_controller *controller);
|
||||||
|
|
||||||
|
#endif
|
Loading…
x
Reference in New Issue
Block a user