Skip to content

Commit

Permalink
Use precise scrolling values
Browse files Browse the repository at this point in the history
Since SDL 2.0.18, the amount scrolled horizontally or vertically is
exposed as a float (between 0 and 1). Forward a precise value to the
Android device when possible.

Refs <https://wiki.libsdl.org/SDL_MouseWheelEvent>
Fixes #3363 <#3363>
PR #3369 <#3369>

Signed-off-by: Romain Vimont <[email protected]>
  • Loading branch information
yume-chan authored and rom1v committed Aug 3, 2022
1 parent 27bbec7 commit 1c785ec
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 30 deletions.
18 changes: 10 additions & 8 deletions app/src/control_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,14 @@ sc_control_msg_serialize(const struct sc_control_msg *msg, unsigned char *buf) {
return 28;
case SC_CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT:
write_position(&buf[1], &msg->inject_scroll_event.position);
sc_write32be(&buf[13],
(uint32_t) msg->inject_scroll_event.hscroll);
sc_write32be(&buf[17],
(uint32_t) msg->inject_scroll_event.vscroll);
sc_write32be(&buf[21], msg->inject_scroll_event.buttons);
return 25;
int16_t hscroll =
sc_float_to_i16fp(msg->inject_scroll_event.hscroll);
int16_t vscroll =
sc_float_to_i16fp(msg->inject_scroll_event.vscroll);
sc_write16be(&buf[13], (uint16_t) hscroll);
sc_write16be(&buf[15], (uint16_t) vscroll);
sc_write32be(&buf[17], msg->inject_scroll_event.buttons);
return 21;
case SC_CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON:
buf[1] = msg->inject_keycode.action;
return 2;
Expand Down Expand Up @@ -181,8 +183,8 @@ sc_control_msg_log(const struct sc_control_msg *msg) {
break;
}
case SC_CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT:
LOG_CMSG("scroll position=%" PRIi32 ",%" PRIi32 " hscroll=%" PRIi32
" vscroll=%" PRIi32 " buttons=%06lx",
LOG_CMSG("scroll position=%" PRIi32 ",%" PRIi32 " hscroll=%f"
" vscroll=%f buttons=%06lx",
msg->inject_scroll_event.position.point.x,
msg->inject_scroll_event.position.point.y,
msg->inject_scroll_event.hscroll,
Expand Down
4 changes: 2 additions & 2 deletions app/src/control_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ struct sc_control_msg {
} inject_touch_event;
struct {
struct sc_position position;
int32_t hscroll;
int32_t vscroll;
float hscroll;
float vscroll;
enum android_motionevent_buttons buttons;
} inject_scroll_event;
struct {
Expand Down
4 changes: 2 additions & 2 deletions app/src/input_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,8 @@ struct sc_mouse_click_event {

struct sc_mouse_scroll_event {
struct sc_position position;
int32_t hscroll;
int32_t vscroll;
float hscroll;
float vscroll;
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
};

Expand Down
9 changes: 7 additions & 2 deletions app/src/input_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -747,8 +747,13 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
.point = sc_screen_convert_window_to_frame_coords(im->screen,
mouse_x, mouse_y),
},
.hscroll = event->x,
.vscroll = event->y,
#if SDL_VERSION_ATLEAST(2, 0, 18)
.hscroll = CLAMP(event->preciseX, -1.0f, 1.0f),
.vscroll = CLAMP(event->preciseY, -1.0f, 1.0f),
#else
.hscroll = CLAMP(event->x, -1, 1),
.vscroll = CLAMP(event->y, -1, 1),
#endif
.buttons_state =
sc_mouse_buttons_state_from_sdl(buttons, im->forward_all_clicks),
};
Expand Down
6 changes: 3 additions & 3 deletions app/tests/test_control_msg_serialize.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,14 +132,14 @@ static void test_serialize_inject_scroll_event(void) {

unsigned char buf[SC_CONTROL_MSG_MAX_SIZE];
size_t size = sc_control_msg_serialize(&msg, buf);
assert(size == 25);
assert(size == 21);

const unsigned char expected[] = {
SC_CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT,
0x00, 0x00, 0x01, 0x04, 0x00, 0x00, 0x04, 0x02, // 260 1026
0x04, 0x38, 0x07, 0x80, // 1080 1920
0x00, 0x00, 0x00, 0x01, // 1
0xFF, 0xFF, 0xFF, 0xFF, // -1
0x7F, 0xFF, // 1 (float encoded as i16)
0x80, 0x00, // -1 (float encoded as i16)
0x00, 0x00, 0x00, 0x01, // 1
};
assert(!memcmp(buf, expected, sizeof(expected)));
Expand Down
10 changes: 5 additions & 5 deletions server/src/main/java/com/genymobile/scrcpy/ControlMessage.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public final class ControlMessage {
private long pointerId;
private float pressure;
private Position position;
private int hScroll;
private int vScroll;
private float hScroll;
private float vScroll;
private int copyKey;
private boolean paste;
private int repeat;
Expand Down Expand Up @@ -71,7 +71,7 @@ public static ControlMessage createInjectTouchEvent(int action, long pointerId,
return msg;
}

public static ControlMessage createInjectScrollEvent(Position position, int hScroll, int vScroll, int buttons) {
public static ControlMessage createInjectScrollEvent(Position position, float hScroll, float vScroll, int buttons) {
ControlMessage msg = new ControlMessage();
msg.type = TYPE_INJECT_SCROLL_EVENT;
msg.position = position;
Expand Down Expand Up @@ -156,11 +156,11 @@ public Position getPosition() {
return position;
}

public int getHScroll() {
public float getHScroll() {
return hScroll;
}

public int getVScroll() {
public float getVScroll() {
return vScroll;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ public class ControlMessageReader {

static final int INJECT_KEYCODE_PAYLOAD_LENGTH = 13;
static final int INJECT_TOUCH_EVENT_PAYLOAD_LENGTH = 27;
static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 24;
static final int INJECT_SCROLL_EVENT_PAYLOAD_LENGTH = 20;
static final int BACK_OR_SCREEN_ON_LENGTH = 1;
static final int SET_SCREEN_POWER_MODE_PAYLOAD_LENGTH = 1;
static final int GET_CLIPBOARD_LENGTH = 1;
Expand Down Expand Up @@ -149,8 +149,8 @@ private ControlMessage parseInjectScrollEvent() {
return null;
}
Position position = readPosition(buffer);
int hScroll = buffer.getInt();
int vScroll = buffer.getInt();
float hScroll = Binary.i16FixedPointToFloat(buffer.getShort());
float vScroll = Binary.i16FixedPointToFloat(buffer.getShort());
int buttons = buffer.getInt();
return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll, buttons);
}
Expand Down
2 changes: 1 addition & 1 deletion server/src/main/java/com/genymobile/scrcpy/Controller.java
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ private boolean injectTouch(int action, long pointerId, Position position, float
return device.injectEvent(event, Device.INJECT_MODE_ASYNC);
}

private boolean injectScroll(Position position, int hScroll, int vScroll, int buttons) {
private boolean injectScroll(Position position, float hScroll, float vScroll, int buttons) {
long now = SystemClock.uptimeMillis();
Point point = device.getPhysicalPoint(position);
if (point == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ public void testParseScrollEvent() throws IOException {
dos.writeInt(1026);
dos.writeShort(1080);
dos.writeShort(1920);
dos.writeInt(1);
dos.writeInt(-1);
dos.writeShort(0); // 0.0f encoded as i16
dos.writeShort(0x8000); // -1.0f encoded as i16
dos.writeInt(1);

byte[] packet = bos.toByteArray();
Expand All @@ -143,8 +143,8 @@ public void testParseScrollEvent() throws IOException {
Assert.assertEquals(1026, event.getPosition().getPoint().getY());
Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
Assert.assertEquals(1, event.getHScroll());
Assert.assertEquals(-1, event.getVScroll());
Assert.assertEquals(0f, event.getHScroll(), 0f);
Assert.assertEquals(-1f, event.getVScroll(), 0f);
Assert.assertEquals(1, event.getButtons());
}

Expand Down

0 comments on commit 1c785ec

Please sign in to comment.