mirror of
https://github.com/Genymobile/scrcpy.git
synced 2025-08-10 01:59:04 +00:00
Handle mouse integer scrolling locally
Do not rely on SDL to expose integer scroll values, as they are not
available in all versions.
It was reimplemented in SDL 3.2.12 by this commit:
<0447c2f3c3
>
Refs #6156 <https://github.com/Genymobile/scrcpy/issues/6156>
This commit is contained in:
parent
f01231dff8
commit
ecde32dd01
9 changed files with 49 additions and 16 deletions
|
@ -166,6 +166,12 @@ sc_hid_buttons_from_buttons_state(uint8_t buttons_state) {
|
|||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
sc_hid_mouse_init(struct sc_hid_mouse *hid) {
|
||||
hid->residual_hscroll = 0;
|
||||
hid->residual_vscroll = 0;
|
||||
}
|
||||
|
||||
void
|
||||
sc_hid_mouse_generate_input_from_motion(struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_motion_event *event) {
|
||||
|
@ -192,22 +198,37 @@ sc_hid_mouse_generate_input_from_click(struct sc_hid_input *hid_input,
|
|||
data[4] = 0; // no horizontal scrolling
|
||||
}
|
||||
|
||||
static int8_t
|
||||
consume_scroll_integer(float *scroll) {
|
||||
float value = CLAMP(*scroll, -127, 127);
|
||||
int8_t consume = value; // truncate towards 0
|
||||
float residual = value - consume;
|
||||
*scroll = residual;
|
||||
return consume;
|
||||
}
|
||||
|
||||
bool
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input,
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_mouse *hid,
|
||||
struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_scroll_event *event) {
|
||||
if (!event->vscroll_int && !event->hscroll_int) {
|
||||
// Need a full integral value for HID
|
||||
sc_hid_mouse_input_init(hid_input);
|
||||
|
||||
hid->residual_hscroll += event->hscroll;
|
||||
hid->residual_vscroll += event->vscroll;
|
||||
int8_t hscroll = consume_scroll_integer(&hid->residual_hscroll);
|
||||
int8_t vscroll = consume_scroll_integer(&hid->residual_vscroll);
|
||||
|
||||
if (!hscroll && !vscroll) {
|
||||
// Not enough scrolling to inject a scroll event
|
||||
return false;
|
||||
}
|
||||
|
||||
sc_hid_mouse_input_init(hid_input);
|
||||
|
||||
uint8_t *data = hid_input->data;
|
||||
data[0] = 0; // buttons state irrelevant (and unknown)
|
||||
data[1] = 0; // no x motion
|
||||
data[2] = 0; // no y motion
|
||||
data[3] = CLAMP(event->vscroll_int, -127, 127);
|
||||
data[4] = CLAMP(event->hscroll_int, -127, 127);
|
||||
data[3] = vscroll;
|
||||
data[4] = hscroll;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,13 @@
|
|||
|
||||
#define SC_HID_ID_MOUSE 2
|
||||
|
||||
struct sc_hid_mouse {
|
||||
float residual_hscroll;
|
||||
float residual_vscroll;
|
||||
};
|
||||
|
||||
void sc_hid_mouse_init(struct sc_hid_mouse *hid);
|
||||
|
||||
void
|
||||
sc_hid_mouse_generate_open(struct sc_hid_open *hid_open);
|
||||
|
||||
|
@ -23,7 +30,8 @@ sc_hid_mouse_generate_input_from_click(struct sc_hid_input *hid_input,
|
|||
const struct sc_mouse_click_event *event);
|
||||
|
||||
bool
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_input *hid_input,
|
||||
sc_hid_mouse_generate_input_from_scroll(struct sc_hid_mouse *hid,
|
||||
struct sc_hid_input *hid_input,
|
||||
const struct sc_mouse_scroll_event *event);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -393,8 +393,6 @@ struct sc_mouse_scroll_event {
|
|||
struct sc_position position;
|
||||
float hscroll;
|
||||
float vscroll;
|
||||
int32_t hscroll_int;
|
||||
int32_t vscroll_int;
|
||||
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
|
||||
};
|
||||
|
||||
|
|
|
@ -903,8 +903,6 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
|
|||
.hscroll = event->x,
|
||||
.vscroll = event->y,
|
||||
#endif
|
||||
.hscroll_int = event->x,
|
||||
.vscroll_int = event->y,
|
||||
.buttons_state = im->mouse_buttons_state,
|
||||
};
|
||||
|
||||
|
|
|
@ -55,7 +55,8 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||
struct sc_mouse_uhid *mouse = DOWNCAST(mp);
|
||||
|
||||
struct sc_hid_input hid_input;
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&hid_input, event)) {
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&mouse->hid, &hid_input,
|
||||
event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -65,6 +66,8 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||
bool
|
||||
sc_mouse_uhid_init(struct sc_mouse_uhid *mouse,
|
||||
struct sc_controller *controller) {
|
||||
sc_hid_mouse_init(&mouse->hid);
|
||||
|
||||
mouse->controller = controller;
|
||||
|
||||
static const struct sc_mouse_processor_ops ops = {
|
||||
|
|
|
@ -4,11 +4,13 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "controller.h"
|
||||
#include "hid/hid_mouse.h"
|
||||
#include "trait/mouse_processor.h"
|
||||
|
||||
struct sc_mouse_uhid {
|
||||
struct sc_mouse_processor mouse_processor; // mouse processor trait
|
||||
|
||||
struct sc_hid_mouse hid;
|
||||
struct sc_controller *controller;
|
||||
};
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||
struct sc_mouse_aoa *mouse = DOWNCAST(mp);
|
||||
|
||||
struct sc_hid_input hid_input;
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&hid_input, event)) {
|
||||
if (!sc_hid_mouse_generate_input_from_scroll(&mouse->hid, &hid_input,
|
||||
event)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -64,6 +65,8 @@ sc_mouse_aoa_init(struct sc_mouse_aoa *mouse, struct sc_aoa *aoa) {
|
|||
return false;
|
||||
}
|
||||
|
||||
sc_hid_mouse_init(&mouse->hid);
|
||||
|
||||
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,
|
||||
|
|
|
@ -6,11 +6,13 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "usb/aoa_hid.h"
|
||||
#include "hid/hid_mouse.h"
|
||||
#include "trait/mouse_processor.h"
|
||||
|
||||
struct sc_mouse_aoa {
|
||||
struct sc_mouse_processor mouse_processor; // mouse processor trait
|
||||
|
||||
struct sc_hid_mouse hid;
|
||||
struct sc_aoa *aoa;
|
||||
};
|
||||
|
||||
|
|
|
@ -171,8 +171,6 @@ sc_screen_otg_process_mouse_wheel(struct sc_screen_otg *screen,
|
|||
.hscroll = event->x,
|
||||
.vscroll = event->y,
|
||||
#endif
|
||||
.hscroll_int = event->x,
|
||||
.vscroll_int = event->y,
|
||||
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue