Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd73a71a15 | ||
|
|
c243fd4c3f | ||
|
|
0bf110dd5c | ||
|
|
0c5e0a4f6d | ||
|
|
0be766e71a | ||
|
|
d02789ce21 | ||
|
|
6cc22e1c5b | ||
|
|
479d10dc22 |
6
BUILD.md
6
BUILD.md
@@ -254,10 +254,10 @@ You can then [run](README.md#run) _scrcpy_.
|
|||||||
|
|
||||||
## Prebuilt server
|
## Prebuilt server
|
||||||
|
|
||||||
- [`scrcpy-server-v1.15.1`][direct-scrcpy-server]
|
- [`scrcpy-server-v1.16`][direct-scrcpy-server]
|
||||||
_(SHA-256: fe06bd6a30da8c89860bf5e16eecce2b5054d4644c84289670ce00ca5d1637c3)_
|
_(SHA-256: 94a79e05b4498d0460ab7bd9d12cbf05156e3a47bf0c5d1420cee1d4493b3832)_
|
||||||
|
|
||||||
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.15.1/scrcpy-server-v1.15.1
|
[direct-scrcpy-server]: https://github.com/Genymobile/scrcpy/releases/download/v1.16/scrcpy-server-v1.16
|
||||||
|
|
||||||
Download the prebuilt server somewhere, and specify its path during the Meson
|
Download the prebuilt server somewhere, and specify its path during the Meson
|
||||||
configuration:
|
configuration:
|
||||||
|
|||||||
2
FAQ.md
2
FAQ.md
@@ -37,6 +37,8 @@ Check [stackoverflow][device-unauthorized].
|
|||||||
|
|
||||||
### Device not detected
|
### Device not detected
|
||||||
|
|
||||||
|
> adb: error: failed to get feature set: no devices/emulators found
|
||||||
|
|
||||||
If your device is not detected, you may need some [drivers] (on Windows).
|
If your device is not detected, you may need some [drivers] (on Windows).
|
||||||
|
|
||||||
[drivers]: https://developer.android.com/studio/run/oem-usb.html
|
[drivers]: https://developer.android.com/studio/run/oem-usb.html
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
# scrcpy (v1.15.1)
|
# scrcpy (v1.16)
|
||||||
|
|
||||||
[Read in another language](#translations)
|
[Read in another language](#translations)
|
||||||
|
|
||||||
@@ -77,10 +77,10 @@ hard).
|
|||||||
For Windows, for simplicity, a prebuilt archive with all the dependencies
|
For Windows, for simplicity, a prebuilt archive with all the dependencies
|
||||||
(including `adb`) is available:
|
(including `adb`) is available:
|
||||||
|
|
||||||
- [`scrcpy-win64-v1.15.1.zip`][direct-win64]
|
- [`scrcpy-win64-v1.16.zip`][direct-win64]
|
||||||
_(SHA-256: 78fba4caad6328016ea93219254b5df391f24224c519a2c8e3f070695b8b38ff)_
|
_(SHA-256: 3f30dc5db1a2f95c2b40a0f5de91ec1642d9f53799250a8c529bc882bc0918f0)_
|
||||||
|
|
||||||
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.15.1/scrcpy-win64-v1.15.1.zip
|
[direct-win64]: https://github.com/Genymobile/scrcpy/releases/download/v1.16/scrcpy-win64-v1.16.zip
|
||||||
|
|
||||||
It is also available in [Chocolatey]:
|
It is also available in [Chocolatey]:
|
||||||
|
|
||||||
|
|||||||
@@ -222,7 +222,7 @@ Default is 0 (automatic).\n
|
|||||||
.SH SHORTCUTS
|
.SH SHORTCUTS
|
||||||
|
|
||||||
In the following list, MOD is the shortcut modifier. By default, it's (left)
|
In the following list, MOD is the shortcut modifier. By default, it's (left)
|
||||||
Alt or (left) Super, but it can be configured by \-\-shortcut-mod.
|
Alt or (left) Super, but it can be configured by \-\-shortcut-mod (see above).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B MOD+f
|
.B MOD+f
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ scrcpy_print_usage(const char *arg0) {
|
|||||||
"\n"
|
"\n"
|
||||||
" In the following list, MOD is the shortcut modifier. By default,\n"
|
" In the following list, MOD is the shortcut modifier. By default,\n"
|
||||||
" it's (left) Alt or (left) Super, but it can be configured by\n"
|
" it's (left) Alt or (left) Super, but it can be configured by\n"
|
||||||
" --shortcut-mod.\n"
|
" --shortcut-mod (see above).\n"
|
||||||
"\n"
|
"\n"
|
||||||
" MOD+f\n"
|
" MOD+f\n"
|
||||||
" Switch fullscreen mode\n"
|
" Switch fullscreen mode\n"
|
||||||
@@ -532,7 +532,9 @@ parse_shortcut_mods_item(const char *item, size_t len) {
|
|||||||
} else if (STREQ("rsuper", item, key_len)) {
|
} else if (STREQ("rsuper", item, key_len)) {
|
||||||
mod |= SC_MOD_RSUPER;
|
mod |= SC_MOD_RSUPER;
|
||||||
} else {
|
} else {
|
||||||
LOGW("Unknown modifier key: %.*s", (int) key_len, item);
|
LOGE("Unknown modifier key: %.*s "
|
||||||
|
"(must be one of: lctrl, rctrl, lalt, ralt, lsuper, rsuper)",
|
||||||
|
(int) key_len, item);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#undef STREQ
|
#undef STREQ
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ enable_tunnel_forward_any_port(struct server *server,
|
|||||||
|
|
||||||
if (port < port_range.last) {
|
if (port < port_range.last) {
|
||||||
LOGW("Could not forward port %" PRIu16", retrying on %" PRIu16,
|
LOGW("Could not forward port %" PRIu16", retrying on %" PRIu16,
|
||||||
port, port + 1);
|
port, (uint16_t) (port + 1));
|
||||||
port++;
|
port++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
// for portability
|
// for portability (kill, readlink, strdup, strtok_r)
|
||||||
#define _POSIX_SOURCE // for kill()
|
#define _POSIX_C_SOURCE 200809L
|
||||||
#define _BSD_SOURCE // for readlink()
|
#define _BSD_SOURCE
|
||||||
|
|
||||||
// modern glibc will complain without this
|
// modern glibc will complain without this
|
||||||
#define _DEFAULT_SOURCE
|
#define _DEFAULT_SOURCE
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ public final class CleanUp {
|
|||||||
|
|
||||||
if (restoreNormalPowerMode) {
|
if (restoreNormalPowerMode) {
|
||||||
Ln.i("Restoring normal power mode");
|
Ln.i("Restoring normal power mode");
|
||||||
Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
|
if (Device.isScreenOn()) {
|
||||||
|
Device.setScreenPowerMode(Device.POWER_MODE_NORMAL);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ public class Controller {
|
|||||||
|
|
||||||
public void control() throws IOException {
|
public void control() throws IOException {
|
||||||
// on start, power on the device
|
// on start, power on the device
|
||||||
if (!device.isScreenOn()) {
|
if (!Device.isScreenOn()) {
|
||||||
device.injectKeycode(KeyEvent.KEYCODE_POWER);
|
device.injectKeycode(KeyEvent.KEYCODE_POWER);
|
||||||
|
|
||||||
// dirty hack
|
// dirty hack
|
||||||
@@ -105,13 +105,13 @@ public class Controller {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
|
case ControlMessage.TYPE_EXPAND_NOTIFICATION_PANEL:
|
||||||
device.expandNotificationPanel();
|
Device.expandNotificationPanel();
|
||||||
break;
|
break;
|
||||||
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
|
case ControlMessage.TYPE_COLLAPSE_NOTIFICATION_PANEL:
|
||||||
device.collapsePanels();
|
Device.collapsePanels();
|
||||||
break;
|
break;
|
||||||
case ControlMessage.TYPE_GET_CLIPBOARD:
|
case ControlMessage.TYPE_GET_CLIPBOARD:
|
||||||
String clipboardText = device.getClipboardText();
|
String clipboardText = Device.getClipboardText();
|
||||||
if (clipboardText != null) {
|
if (clipboardText != null) {
|
||||||
sender.pushClipboardText(clipboardText);
|
sender.pushClipboardText(clipboardText);
|
||||||
}
|
}
|
||||||
@@ -130,7 +130,7 @@ public class Controller {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ControlMessage.TYPE_ROTATE_DEVICE:
|
case ControlMessage.TYPE_ROTATE_DEVICE:
|
||||||
device.rotateDevice();
|
Device.rotateDevice();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// do nothing
|
// do nothing
|
||||||
@@ -248,7 +248,7 @@ public class Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean pressBackOrTurnScreenOn() {
|
private boolean pressBackOrTurnScreenOn() {
|
||||||
int keycode = device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_POWER;
|
int keycode = Device.isScreenOn() ? KeyEvent.KEYCODE_BACK : KeyEvent.KEYCODE_POWER;
|
||||||
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_POWER) {
|
if (keepPowerModeOff && keycode == KeyEvent.KEYCODE_POWER) {
|
||||||
schedulePowerModeOff();
|
schedulePowerModeOff();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,8 @@ public final class Device {
|
|||||||
public static final int POWER_MODE_OFF = SurfaceControl.POWER_MODE_OFF;
|
public static final int POWER_MODE_OFF = SurfaceControl.POWER_MODE_OFF;
|
||||||
public static final int POWER_MODE_NORMAL = SurfaceControl.POWER_MODE_NORMAL;
|
public static final int POWER_MODE_NORMAL = SurfaceControl.POWER_MODE_NORMAL;
|
||||||
|
|
||||||
|
private static final ServiceManager SERVICE_MANAGER = new ServiceManager();
|
||||||
|
|
||||||
public interface RotationListener {
|
public interface RotationListener {
|
||||||
void onRotationChanged(int rotation);
|
void onRotationChanged(int rotation);
|
||||||
}
|
}
|
||||||
@@ -33,8 +35,6 @@ public final class Device {
|
|||||||
void onClipboardTextChanged(String text);
|
void onClipboardTextChanged(String text);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ServiceManager serviceManager = new ServiceManager();
|
|
||||||
|
|
||||||
private ScreenInfo screenInfo;
|
private ScreenInfo screenInfo;
|
||||||
private RotationListener rotationListener;
|
private RotationListener rotationListener;
|
||||||
private ClipboardListener clipboardListener;
|
private ClipboardListener clipboardListener;
|
||||||
@@ -54,9 +54,9 @@ public final class Device {
|
|||||||
|
|
||||||
public Device(Options options) {
|
public Device(Options options) {
|
||||||
displayId = options.getDisplayId();
|
displayId = options.getDisplayId();
|
||||||
DisplayInfo displayInfo = serviceManager.getDisplayManager().getDisplayInfo(displayId);
|
DisplayInfo displayInfo = SERVICE_MANAGER.getDisplayManager().getDisplayInfo(displayId);
|
||||||
if (displayInfo == null) {
|
if (displayInfo == null) {
|
||||||
int[] displayIds = serviceManager.getDisplayManager().getDisplayIds();
|
int[] displayIds = SERVICE_MANAGER.getDisplayManager().getDisplayIds();
|
||||||
throw new InvalidDisplayIdException(displayId, displayIds);
|
throw new InvalidDisplayIdException(displayId, displayIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ public final class Device {
|
|||||||
screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize(), options.getLockedVideoOrientation());
|
screenInfo = ScreenInfo.computeScreenInfo(displayInfo, options.getCrop(), options.getMaxSize(), options.getLockedVideoOrientation());
|
||||||
layerStack = displayInfo.getLayerStack();
|
layerStack = displayInfo.getLayerStack();
|
||||||
|
|
||||||
serviceManager.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() {
|
SERVICE_MANAGER.getWindowManager().registerRotationWatcher(new IRotationWatcher.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void onRotationChanged(int rotation) {
|
public void onRotationChanged(int rotation) {
|
||||||
synchronized (Device.this) {
|
synchronized (Device.this) {
|
||||||
@@ -81,7 +81,7 @@ public final class Device {
|
|||||||
|
|
||||||
if (options.getControl()) {
|
if (options.getControl()) {
|
||||||
// If control is enabled, synchronize Android clipboard to the computer automatically
|
// If control is enabled, synchronize Android clipboard to the computer automatically
|
||||||
ClipboardManager clipboardManager = serviceManager.getClipboardManager();
|
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
|
||||||
if (clipboardManager != null) {
|
if (clipboardManager != null) {
|
||||||
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
|
clipboardManager.addPrimaryClipChangedListener(new IOnPrimaryClipChangedListener.Stub() {
|
||||||
@Override
|
@Override
|
||||||
@@ -166,7 +166,7 @@ public final class Device {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return serviceManager.getInputManager().injectInputEvent(inputEvent, mode);
|
return SERVICE_MANAGER.getInputManager().injectInputEvent(inputEvent, mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean injectEvent(InputEvent event) {
|
public boolean injectEvent(InputEvent event) {
|
||||||
@@ -184,8 +184,8 @@ public final class Device {
|
|||||||
return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0) && injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0);
|
return injectKeyEvent(KeyEvent.ACTION_DOWN, keyCode, 0, 0) && injectKeyEvent(KeyEvent.ACTION_UP, keyCode, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isScreenOn() {
|
public static boolean isScreenOn() {
|
||||||
return serviceManager.getPowerManager().isScreenOn();
|
return SERVICE_MANAGER.getPowerManager().isScreenOn();
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void setRotationListener(RotationListener rotationListener) {
|
public synchronized void setRotationListener(RotationListener rotationListener) {
|
||||||
@@ -196,16 +196,16 @@ public final class Device {
|
|||||||
this.clipboardListener = clipboardListener;
|
this.clipboardListener = clipboardListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void expandNotificationPanel() {
|
public static void expandNotificationPanel() {
|
||||||
serviceManager.getStatusBarManager().expandNotificationsPanel();
|
SERVICE_MANAGER.getStatusBarManager().expandNotificationsPanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void collapsePanels() {
|
public static void collapsePanels() {
|
||||||
serviceManager.getStatusBarManager().collapsePanels();
|
SERVICE_MANAGER.getStatusBarManager().collapsePanels();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getClipboardText() {
|
public static String getClipboardText() {
|
||||||
ClipboardManager clipboardManager = serviceManager.getClipboardManager();
|
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
|
||||||
if (clipboardManager == null) {
|
if (clipboardManager == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -217,7 +217,7 @@ public final class Device {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean setClipboardText(String text) {
|
public boolean setClipboardText(String text) {
|
||||||
ClipboardManager clipboardManager = serviceManager.getClipboardManager();
|
ClipboardManager clipboardManager = SERVICE_MANAGER.getClipboardManager();
|
||||||
if (clipboardManager == null) {
|
if (clipboardManager == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -252,8 +252,8 @@ public final class Device {
|
|||||||
/**
|
/**
|
||||||
* Disable auto-rotation (if enabled), set the screen rotation and re-enable auto-rotation (if it was enabled).
|
* Disable auto-rotation (if enabled), set the screen rotation and re-enable auto-rotation (if it was enabled).
|
||||||
*/
|
*/
|
||||||
public void rotateDevice() {
|
public static void rotateDevice() {
|
||||||
WindowManager wm = serviceManager.getWindowManager();
|
WindowManager wm = SERVICE_MANAGER.getWindowManager();
|
||||||
|
|
||||||
boolean accelerometerRotation = !wm.isRotationFrozen();
|
boolean accelerometerRotation = !wm.isRotationFrozen();
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ public final class Device {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ContentProvider createSettingsProvider() {
|
public static ContentProvider createSettingsProvider() {
|
||||||
return serviceManager.getActivityManager().createSettingsProvider();
|
return SERVICE_MANAGER.getActivityManager().createSettingsProvider();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public final class Server {
|
|||||||
boolean mustDisableShowTouchesOnCleanUp = false;
|
boolean mustDisableShowTouchesOnCleanUp = false;
|
||||||
int restoreStayOn = -1;
|
int restoreStayOn = -1;
|
||||||
if (options.getShowTouches() || options.getStayAwake()) {
|
if (options.getShowTouches() || options.getStayAwake()) {
|
||||||
try (ContentProvider settings = device.createSettingsProvider()) {
|
try (ContentProvider settings = Device.createSettingsProvider()) {
|
||||||
if (options.getShowTouches()) {
|
if (options.getShowTouches()) {
|
||||||
String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
|
String oldValue = settings.getAndPutValue(ContentProvider.TABLE_SYSTEM, "show_touches", "1");
|
||||||
// If "show touches" was disabled, it must be disabled back on clean up
|
// If "show touches" was disabled, it must be disabled back on clean up
|
||||||
|
|||||||
Reference in New Issue
Block a user