From 0889a66d95fa6bcd038a7e41b9303f0ef8e6cc65 Mon Sep 17 00:00:00 2001 From: Simon Chan <1330321+yume-chan@users.noreply.github.com> Date: Wed, 6 Jul 2022 05:32:32 +0000 Subject: [PATCH] handle float scroll distance in protocol level --- app/src/control_msg.c | 21 +++++++++++-------- app/src/control_msg.h | 4 ++-- app/src/input_events.h | 4 ++-- app/src/input_manager.c | 16 ++++++++++++-- .../scrcpy/ControlMessageReader.java | 10 ++++----- .../scrcpy/ControlMessageReaderTest.java | 6 +++--- 6 files changed, 38 insertions(+), 23 deletions(-) diff --git a/app/src/control_msg.c b/app/src/control_msg.c index a57d8cc2..41c7762a 100644 --- a/app/src/control_msg.c +++ b/app/src/control_msg.c @@ -115,12 +115,15 @@ 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; + // map [-1, 1] to [0, 1], then to uint16 + uint16_t hscroll = + to_fixed_point_16((msg->inject_scroll_event.hscroll + 1.0f) / 2.0f); + uint16_t vscroll = + to_fixed_point_16((msg->inject_scroll_event.vscroll + 1.0f) / 2.0f); + sc_write16be(&buf[13], hscroll); + sc_write16be(&buf[15], 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; @@ -180,7 +183,7 @@ sc_control_msg_log(const struct sc_control_msg *msg) { } else { // numeric pointer id LOG_CMSG("touch [id=%" PRIu64_ "] %-4s position=%" PRIi32 ",%" - PRIi32 " pressure=%g buttons=%06lx", + PRIi32 " pressure=%f buttons=%06lx", id, MOTIONEVENT_ACTION_LABEL(action), msg->inject_touch_event.position.point.x, @@ -191,8 +194,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 a8841553..f66d703e 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -741,14 +741,26 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im, int mouse_y; uint32_t buttons = SDL_GetMouseState(&mouse_x, &mouse_y); + float hscroll; + float vscroll; + if (SDL_VERSION_ATLEAST(2, 0, 18)) { + // right is positive + hscroll = CLAMP(-event->preciseX, -1.0f, 1.0f); + // up is positive + vscroll = CLAMP(event->preciseY, -1.0f, 1.0f); + } else { + hscroll = CLAMP(-event->x, -1, 1); + vscroll = CLAMP(event->y, -1, 1); + } + struct sc_mouse_scroll_event evt = { .position = { .screen_size = im->screen->frame_size, .point = sc_screen_convert_window_to_frame_coords(im->screen, mouse_x, mouse_y), }, - .hscroll = (int32_t)(event->preciseX * 1000), - .vscroll = (int32_t)(event->preciseY * 1000), + .hscroll = hscroll, + .vscroll = vscroll, .buttons_state = sc_mouse_buttons_state_from_sdl(buttons, im->forward_all_clicks), }; diff --git a/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java b/server/src/main/java/com/genymobile/scrcpy/ControlMessageReader.java index edabd0a2..787aca23 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; @@ -152,10 +152,10 @@ public class ControlMessageReader { return null; } Position position = readPosition(buffer); - int hScrollInt = buffer.getInt(); - int vScrollInt = buffer.getInt(); - float hScroll = hScrollInt / 1000f; - float vScroll = vScrollInt / 1000f; + int hScrollInt = toUnsigned(buffer.getShort()); + int vScrollInt = toUnsigned(buffer.getShort()); + float hScroll = hScrollInt == 0xffff ? 1f : ((hScrollInt - 0x8000) / 0x1p15f); + float vScroll = vScrollInt == 0xffff ? 1f : ((vScrollInt - 0x8000) / 0x1p15f); int buttons = buffer.getInt(); return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll, buttons); } diff --git a/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java b/server/src/test/java/com/genymobile/scrcpy/ControlMessageReaderTest.java index 843d7e88..8c089235 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(1000); - dos.writeInt(-1000); + dos.writeShort(0x8000); + dos.writeShort(0); dos.writeInt(1); byte[] packet = bos.toByteArray(); @@ -143,7 +143,7 @@ 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(1f, event.getHScroll(), 0f); + Assert.assertEquals(0f, event.getHScroll(), 0f); Assert.assertEquals(-1f, event.getVScroll(), 0f); Assert.assertEquals(1, event.getButtons()); }