mirror of
https://github.com/Genymobile/scrcpy
synced 2025-01-18 05:01:00 +00:00
Introduce PositionMapper
Extract the function that converts coordinates from video space to display space into a separate component. It only requires the specific data it uses and does not need a full ScreenInfo object (although it can be created from a ScreenInfo instance). PR #5370 <https://github.com/Genymobile/scrcpy/pull/5370>
This commit is contained in:
parent
d916429566
commit
f1368d9a8f
@ -0,0 +1,48 @@
|
||||
package com.genymobile.scrcpy.control;
|
||||
|
||||
import com.genymobile.scrcpy.device.Point;
|
||||
import com.genymobile.scrcpy.device.Position;
|
||||
import com.genymobile.scrcpy.device.Size;
|
||||
import com.genymobile.scrcpy.video.ScreenInfo;
|
||||
|
||||
import android.graphics.Rect;
|
||||
|
||||
public final class PositionMapper {
|
||||
|
||||
private final Size videoSize;
|
||||
private final Rect contentRect;
|
||||
private final int coordsRotation;
|
||||
|
||||
public PositionMapper(Size videoSize, Rect contentRect, int videoRotation) {
|
||||
this.videoSize = videoSize;
|
||||
this.contentRect = contentRect;
|
||||
this.coordsRotation = reverseRotation(videoRotation);
|
||||
}
|
||||
|
||||
public static PositionMapper from(ScreenInfo screenInfo) {
|
||||
// ignore the locked video orientation, the events will apply in coordinates considered in the physical device orientation
|
||||
Size videoSize = screenInfo.getUnlockedVideoSize();
|
||||
return new PositionMapper(videoSize, screenInfo.getContentRect(), screenInfo.getVideoRotation());
|
||||
}
|
||||
|
||||
private static int reverseRotation(int rotation) {
|
||||
return (4 - rotation) % 4;
|
||||
}
|
||||
|
||||
public Point map(Position position) {
|
||||
// reverse the video rotation to apply the events
|
||||
Position devicePosition = position.rotate(coordsRotation);
|
||||
|
||||
Size clientVideoSize = devicePosition.getScreenSize();
|
||||
if (!videoSize.equals(clientVideoSize)) {
|
||||
// The client sends a click relative to a video with wrong dimensions,
|
||||
// the device may have been rotated since the event was generated, so ignore the event
|
||||
return null;
|
||||
}
|
||||
|
||||
Point point = devicePosition.getPoint();
|
||||
int convertedX = contentRect.left + point.getX() * contentRect.width() / videoSize.getWidth();
|
||||
int convertedY = contentRect.top + point.getY() * contentRect.height() / videoSize.getHeight();
|
||||
return new Point(convertedX, convertedY);
|
||||
}
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
package com.genymobile.scrcpy.device;
|
||||
|
||||
import com.genymobile.scrcpy.AndroidVersions;
|
||||
import com.genymobile.scrcpy.control.PositionMapper;
|
||||
import com.genymobile.scrcpy.util.Ln;
|
||||
import com.genymobile.scrcpy.video.ScreenInfo;
|
||||
import com.genymobile.scrcpy.wrappers.ClipboardManager;
|
||||
import com.genymobile.scrcpy.wrappers.DisplayControl;
|
||||
import com.genymobile.scrcpy.wrappers.InputManager;
|
||||
@ -10,7 +10,6 @@ import com.genymobile.scrcpy.wrappers.ServiceManager;
|
||||
import com.genymobile.scrcpy.wrappers.SurfaceControl;
|
||||
import com.genymobile.scrcpy.wrappers.WindowManager;
|
||||
|
||||
import android.graphics.Rect;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.SystemClock;
|
||||
@ -33,34 +32,17 @@ public final class Device {
|
||||
public static final int LOCK_VIDEO_ORIENTATION_UNLOCKED = -1;
|
||||
public static final int LOCK_VIDEO_ORIENTATION_INITIAL = -2;
|
||||
|
||||
private final AtomicReference<ScreenInfo> screenInfo = new AtomicReference<>(); // set by the ScreenCapture instance
|
||||
private final AtomicReference<PositionMapper> positionMapper = new AtomicReference<>(); // set by the ScreenCapture instance
|
||||
|
||||
public Point getPhysicalPoint(Position position) {
|
||||
// it hides the field on purpose, to read it with atomic access
|
||||
@SuppressWarnings("checkstyle:HiddenField")
|
||||
ScreenInfo screenInfo = this.screenInfo.get();
|
||||
if (screenInfo == null) {
|
||||
PositionMapper positionMapper = this.positionMapper.get();
|
||||
if (positionMapper == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// ignore the locked video orientation, the events will apply in coordinates considered in the physical device orientation
|
||||
Size unlockedVideoSize = screenInfo.getUnlockedVideoSize();
|
||||
|
||||
int reverseVideoRotation = screenInfo.getReverseVideoRotation();
|
||||
// reverse the video rotation to apply the events
|
||||
Position devicePosition = position.rotate(reverseVideoRotation);
|
||||
|
||||
Size clientVideoSize = devicePosition.getScreenSize();
|
||||
if (!unlockedVideoSize.equals(clientVideoSize)) {
|
||||
// The client sends a click relative to a video with wrong dimensions,
|
||||
// the device may have been rotated since the event was generated, so ignore the event
|
||||
return null;
|
||||
}
|
||||
Rect contentRect = screenInfo.getContentRect();
|
||||
Point point = devicePosition.getPoint();
|
||||
int convertedX = contentRect.left + point.getX() * contentRect.width() / unlockedVideoSize.getWidth();
|
||||
int convertedY = contentRect.top + point.getY() * contentRect.height() / unlockedVideoSize.getHeight();
|
||||
return new Point(convertedX, convertedY);
|
||||
return positionMapper.map(position);
|
||||
}
|
||||
|
||||
public static String getDeviceName() {
|
||||
@ -72,8 +54,8 @@ public final class Device {
|
||||
return displayId == 0 || Build.VERSION.SDK_INT >= AndroidVersions.API_29_ANDROID_10;
|
||||
}
|
||||
|
||||
public void setScreenInfo(ScreenInfo screenInfo) {
|
||||
this.screenInfo.set(screenInfo);
|
||||
public void setPositionMapper(PositionMapper positionMapper) {
|
||||
this.positionMapper.set(positionMapper);
|
||||
}
|
||||
|
||||
public static boolean injectEvent(InputEvent inputEvent, int displayId, int injectMode) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.genymobile.scrcpy.video;
|
||||
|
||||
import com.genymobile.scrcpy.AndroidVersions;
|
||||
import com.genymobile.scrcpy.control.PositionMapper;
|
||||
import com.genymobile.scrcpy.device.ConfigurationException;
|
||||
import com.genymobile.scrcpy.device.Device;
|
||||
import com.genymobile.scrcpy.device.DisplayInfo;
|
||||
@ -132,7 +133,8 @@ public class ScreenCapture extends SurfaceCapture {
|
||||
}
|
||||
}
|
||||
|
||||
device.setScreenInfo(screenInfo);
|
||||
PositionMapper positionMapper = PositionMapper.from(screenInfo);
|
||||
device.setPositionMapper(positionMapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user