Extend value range for SDK mouse scrolling

SDL precise scrolling can sometimes produce values greater than 1 or
less than -1.

On the wire, the value is encoded as a 16-bit fixed-point number.

Previously, the range was interpreted as [-1, 1], using 1 bit for the
integral part (the sign) and 15 bits for the fractional part.

To support larger values, interpret the range as [-16, 16] instead,
using 5 bits for the integral part and 11 bits for the fractional part
(which is more than enough).

PR #6172 <https://github.com/Genymobile/scrcpy/pull/6172>
This commit is contained in:
Romain Vimont
2025-06-20 09:06:10 +02:00
parent 9787fe5d26
commit 7c8bdccbdc
5 changed files with 19 additions and 14 deletions

View File

@@ -112,8 +112,9 @@ public class ControlMessageReader {
private ControlMessage parseInjectScrollEvent() throws IOException {
Position position = parsePosition();
float hScroll = Binary.i16FixedPointToFloat(dis.readShort());
float vScroll = Binary.i16FixedPointToFloat(dis.readShort());
// Binary.i16FixedPointToFloat() decodes values assuming the full range is [-1, 1], but the actual range is [-16, 16].
float hScroll = Binary.i16FixedPointToFloat(dis.readShort()) * 16;
float vScroll = Binary.i16FixedPointToFloat(dis.readShort()) * 16;
int buttons = dis.readInt();
return ControlMessage.createInjectScrollEvent(position, hScroll, vScroll, buttons);
}

View File

@@ -125,7 +125,7 @@ public class ControlMessageReaderTest {
dos.writeShort(1080);
dos.writeShort(1920);
dos.writeShort(0); // 0.0f encoded as i16
dos.writeShort(0x8000); // -1.0f encoded as i16
dos.writeShort(0x8000); // -16.0f encoded as i16 (the range is [-16, 16])
dos.writeInt(1);
byte[] packet = bos.toByteArray();
@@ -139,7 +139,7 @@ public class ControlMessageReaderTest {
Assert.assertEquals(1080, event.getPosition().getScreenSize().getWidth());
Assert.assertEquals(1920, event.getPosition().getScreenSize().getHeight());
Assert.assertEquals(0f, event.getHScroll(), 0f);
Assert.assertEquals(-1f, event.getVScroll(), 0f);
Assert.assertEquals(-16f, event.getVScroll(), 0f);
Assert.assertEquals(1, event.getButtons());
Assert.assertEquals(-1, bis.read()); // EOS