From 57056d078ddcac73fe10fcb41395ed21f3d486b6 Mon Sep 17 00:00:00 2001 From: Simon Chan <1330321+yume-chan@users.noreply.github.com> Date: Sun, 3 Jul 2022 07:02:17 +0000 Subject: [PATCH] Use precise scrolling values 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 Fixes #3363 PR #3369 Signed-off-by: Romain Vimont --- app/src/control_msg.c | 18 ++++++++++-------- app/src/control_msg.h | 4 ++-- app/src/input_events.h | 4 ++-- app/src/input_manager.c | 9 +++++++-- app/tests/test_control_msg_serialize.c | 6 +++--- .../com/genymobile/scrcpy/ControlMessage.java | 10 +++++----- .../scrcpy/ControlMessageReader.java | 6 +++--- .../java/com/genymobile/scrcpy/Controller.java | 2 +- .../scrcpy/ControlMessageReaderTest.java | 8 ++++---- 9 files changed, 37 insertions(+), 30 deletions(-) diff --git a/app/src/control_msg.c b/app/src/control_msg.c index 4aa0944c..3513abc7 100644 --- a/app/src/control_msg.c +++ b/app/src/control_msg.c @@ -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; @@ -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, diff --git a/app/src/control_msg.h b/app/src/control_msg.h index 1463fddc..f51bdecd 100644 --- a/app/src/control_msg.h +++ b/app/src/control_msg.h @@ -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 { diff --git a/app/src/input_events.h b/app/src/input_events.h index 9bf3c421..15d22910 100644 --- a/app/src/input_events.h +++ b/app/src/input_events.h @@ -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 }; diff --git a/app/src/input_manager.c b/app/src/input_manager.c index bba3665c..42b49a13 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -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), }; diff --git a/app/tests/test_control_msg_serialize.c b/app/tests/test_control_msg_serialize.c index 72e3d87a..87117e3a 100644 --- a/app/tests/test_control_msg_serialize.c +++ b/app/tests/test_control_msg_serialize.c @@ -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))); diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java index 99eb805f..0b05b22a 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessage.java @@ -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; @@ -71,7 +71,7 @@ public final class ControlMessage { 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; @@ -156,11 +156,11 @@ public final class ControlMessage { return position; } - public int getHScroll() { + public float getHScroll() { return hScroll; } - public int getVScroll() { + public float getVScroll() { return vScroll; } diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java index b2d500c2..a52fd134 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java +++ b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java @@ -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; @@ -149,8 +149,8 @@ public class ControlMessageReader { 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); } diff --git a/server/src/main/java/com/genymobile/scrcpy/Controller.java b/server/src/main/java/com/genymobile/scrcpy/Controller.java index 913371ee..95b64711 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Controller.java +++ b/server/src/main/java/com/genymobile/scrcpy/Controller.java @@ -223,7 +223,7 @@ public class Controller { 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) { diff --git a/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java b/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java index 2a4ffe75..1fc009ce 100644 --- a/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java +++ b/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java @@ -126,8 +126,8 @@ public class ControlMessageReaderTest { 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(); @@ -143,8 +143,8 @@ public class ControlMessageReaderTest { 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()); }